Merge jdk9-b30
authorduke
Wed, 05 Jul 2017 20:00:07 +0200
changeset 26395 b2287cac7813
parent 26394 bcf7be47a0ac (diff)
parent 26280 5e26b7d46938 (current diff)
child 26396 85ff2cbb59dd
child 26397 c0b8b00b9c06
child 26404 a6c09252a750
child 26407 aa2cf3f6c4f3
child 26443 334723de947f
child 26447 e0c04e7e268a
child 26483 c0920178d0be
child 26494 50e227011f5a
child 26495 63334d13d565
child 26498 29d597edef7c
child 26509 00cc73c2862d
child 26515 8aa74cd4155b
child 26518 7f4dffefafa7
child 26522 18c951dd2352
child 26523 82811adf47a3
child 26526 6644f0e5ae7e
child 26538 623363d962c9
Merge
--- a/.hgtags-top-repo	Wed Jul 05 19:59:05 2017 +0200
+++ b/.hgtags-top-repo	Wed Jul 05 20:00:07 2017 +0200
@@ -271,3 +271,4 @@
 d3ec8d048e6c3c46b6e0ee011cc551ad386dfba5 jdk9-b26
 ba5645f2735b41ed085d07ba20fa7b322afff318 jdk9-b27
 ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28
+9e6581aeda388a23fbee021fc33e6aa152a60657 jdk9-b29
--- a/corba/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/corba/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -271,3 +271,4 @@
 6c777df597bbf5abba3488d44c401edfe73c74af jdk9-b26
 7e06bf1dcb0907b80ddf59315426ce9ce775e56d jdk9-b27
 a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28
+163a9cd806fd09970baf1f5f42b92a3cfe7ee945 jdk9-b29
--- a/hotspot/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -431,3 +431,4 @@
 48b95a073d752d6891cc0d1d2836b321ecf3ce0c jdk9-b26
 f95347244306affc32ce3056f27ceff7b2100810 jdk9-b27
 657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28
+deb29e92f68ace2808a36ecfa18c7d61dcb645bb jdk9-b29
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1CollectedHeap.java	Wed Jul 05 20:00:07 2017 +0200
@@ -43,8 +43,8 @@
 // Mirror class for G1CollectedHeap.
 
 public class G1CollectedHeap extends SharedHeap {
-    // HeapRegionSeq _seq;
-    static private long hrsFieldOffset;
+    // HeapRegionManager _hrm;
+    static private long hrmFieldOffset;
     // MemRegion _g1_reserved;
     static private long g1ReservedFieldOffset;
     // size_t _summary_bytes_used;
@@ -67,7 +67,7 @@
     static private synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("G1CollectedHeap");
 
-        hrsFieldOffset = type.getField("_hrs").getOffset();
+        hrmFieldOffset = type.getField("_hrm").getOffset();
         summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
         g1mmField = type.getAddressField("_g1mm");
         oldSetFieldOffset = type.getField("_old_set").getOffset();
@@ -75,7 +75,7 @@
     }
 
     public long capacity() {
-        return hrs().capacity();
+        return hrm().capacity();
     }
 
     public long used() {
@@ -83,13 +83,13 @@
     }
 
     public long n_regions() {
-        return hrs().length();
+        return hrm().length();
     }
 
-    private HeapRegionSeq hrs() {
-        Address hrsAddr = addr.addOffsetTo(hrsFieldOffset);
-        return (HeapRegionSeq) VMObjectFactory.newObject(HeapRegionSeq.class,
-                                                         hrsAddr);
+    private HeapRegionManager hrm() {
+        Address hrmAddr = addr.addOffsetTo(hrmFieldOffset);
+        return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class,
+                                                         hrmAddr);
     }
 
     public G1MonitoringSupport g1mm() {
@@ -110,7 +110,7 @@
     }
 
     private Iterator<HeapRegion> heapRegionIterator() {
-        return hrs().heapRegionIterator();
+        return hrm().heapRegionIterator();
     }
 
     public void heapRegionIterate(SpaceClosure scl) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionManager.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.gc_implementation.g1;
+
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObject;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+// Mirror class for HeapRegionManager.
+
+public class HeapRegionManager extends VMObject {
+    // G1HeapRegionTable _regions
+    static private long regionsFieldOffset;
+    // uint _committed_length
+    static private CIntegerField numCommittedField;
+
+    static {
+        VM.registerVMInitializedObserver(new Observer() {
+                public void update(Observable o, Object data) {
+                    initialize(VM.getVM().getTypeDataBase());
+                }
+            });
+    }
+
+    static private synchronized void initialize(TypeDataBase db) {
+        Type type = db.lookupType("HeapRegionManager");
+
+        regionsFieldOffset = type.getField("_regions").getOffset();
+        numCommittedField = type.getCIntegerField("_num_committed");
+    }
+
+    private G1HeapRegionTable regions() {
+        Address regionsAddr = addr.addOffsetTo(regionsFieldOffset);
+        return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class,
+                                                             regionsAddr);
+    }
+
+    public long capacity() {
+        return length() * HeapRegion.grainBytes();
+    }
+
+    public long length() {
+        return regions().length();
+    }
+
+    public long committedLength() {
+        return numCommittedField.getValue(addr);
+    }
+
+    public Iterator<HeapRegion> heapRegionIterator() {
+        return regions().heapRegionIterator(length());
+    }
+
+    public HeapRegionManager(Address addr) {
+        super(addr);
+    }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.gc_implementation.g1;
-
-import java.util.Iterator;
-import java.util.Observable;
-import java.util.Observer;
-
-import sun.jvm.hotspot.debugger.Address;
-import sun.jvm.hotspot.runtime.VM;
-import sun.jvm.hotspot.runtime.VMObject;
-import sun.jvm.hotspot.runtime.VMObjectFactory;
-import sun.jvm.hotspot.types.AddressField;
-import sun.jvm.hotspot.types.CIntegerField;
-import sun.jvm.hotspot.types.Type;
-import sun.jvm.hotspot.types.TypeDataBase;
-
-// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable.
-
-public class HeapRegionSeq extends VMObject {
-    // G1HeapRegionTable _regions
-    static private long regionsFieldOffset;
-    // uint _committed_length
-    static private CIntegerField numCommittedField;
-
-    static {
-        VM.registerVMInitializedObserver(new Observer() {
-                public void update(Observable o, Object data) {
-                    initialize(VM.getVM().getTypeDataBase());
-                }
-            });
-    }
-
-    static private synchronized void initialize(TypeDataBase db) {
-        Type type = db.lookupType("HeapRegionSeq");
-
-        regionsFieldOffset = type.getField("_regions").getOffset();
-        numCommittedField = type.getCIntegerField("_num_committed");
-    }
-
-    private G1HeapRegionTable regions() {
-        Address regionsAddr = addr.addOffsetTo(regionsFieldOffset);
-        return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class,
-                                                             regionsAddr);
-    }
-
-    public long capacity() {
-        return length() * HeapRegion.grainBytes();
-    }
-
-    public long length() {
-        return regions().length();
-    }
-
-    public long committedLength() {
-        return numCommittedField.getValue(addr);
-    }
-
-    public Iterator<HeapRegion> heapRegionIterator() {
-        return regions().heapRegionIterator(length());
-    }
-
-    public HeapRegionSeq(Address addr) {
-        super(addr);
-    }
-}
--- a/hotspot/make/Makefile	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/make/Makefile	Wed Jul 05 20:00:07 2017 +0200
@@ -721,6 +721,19 @@
 	   ($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
 	fi
 
+copy_optimized_jdk::
+	$(RM) -r $(JDK_IMAGE_DIR)/optimized
+	$(MKDIR) -p $(JDK_IMAGE_DIR)/optimized
+	if [ -d $(JDK_IMPORT_PATH)/optimized ] ; then \
+	  ($(CD) $(JDK_IMPORT_PATH)/optimized && \
+	   $(TAR) -cf - $(JDK_DIRS)) | \
+	   ($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
+	else \
+	  ($(CD) $(JDK_IMPORT_PATH) && \
+	   $(TAR) -cf - $(JDK_DIRS)) | \
+	   ($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
+	fi
+
 #
 # Check target
 #
--- a/hotspot/make/jprt.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/make/jprt.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -42,6 +42,9 @@
 jprt_build_fastdebugEmb:
 	$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
 
+jprt_build_optimizedEmb:
+	$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_optimized
+
 jprt_build_productOpen:
 	$(MAKE) OPENJDK=true jprt_build_product
 
@@ -51,6 +54,9 @@
 jprt_build_fastdebugOpen:
 	$(MAKE) OPENJDK=true jprt_build_fastdebug
 
+jprt_build_optimizedOpen:
+	$(MAKE) OPENJDK=true jprt_build_optimized
+
 jprt_build_product: all_product copy_product_jdk export_product_jdk
 	( $(CD) $(JDK_IMAGE_DIR) && \
 	  $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
@@ -63,5 +69,9 @@
 	( $(CD) $(JDK_IMAGE_DIR)/debug && \
 	  $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
 
-.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug
+jprt_build_optimized: all_optimized copy_optimized_jdk export_optimized_jdk
+	( $(CD) $(JDK_IMAGE_DIR)/optimized && \
+	  $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
 
+.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug jprt_build_optimized
+
--- a/hotspot/make/jprt.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/make/jprt.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -93,13 +93,13 @@
 # Standard list of jprt build targets for this source tree
 
 jprt.build.targets.standard= \
-    ${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \
+    ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
     ${jprt.my.solaris.x64}-{product|fastdebug}, \
     ${jprt.my.linux.i586}-{product|fastdebug}, \
-    ${jprt.my.linux.x64}-{product|fastdebug|optimized}, \
+    ${jprt.my.linux.x64}-{product|fastdebug}, \
     ${jprt.my.macosx.x64}-{product|fastdebug}, \
     ${jprt.my.windows.i586}-{product|fastdebug}, \
-    ${jprt.my.windows.x64}-{product|fastdebug|optimized}, \
+    ${jprt.my.windows.x64}-{product|fastdebug}, \
     ${jprt.my.linux.armvh}-{product|fastdebug}
 
 jprt.build.targets.open= \
--- a/hotspot/make/windows/makefiles/vm.make	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/make/windows/makefiles/vm.make	Wed Jul 05 20:00:07 2017 +0200
@@ -34,6 +34,9 @@
 CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT"
 !else
 CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
+!if "$(BUILDARCH)" == "amd64"
+CXX_FLAGS=$(CXX_FLAGS) /homeparams
+!endif
 !endif
 
 !if "$(Variant)" == "compiler1"
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -604,6 +604,17 @@
 
 #if INCLUDE_RTM_OPT
   if (UseRTMLocking) {
+    if (is_intel_family_core()) {
+      if ((_model == CPU_MODEL_HASWELL_E3) ||
+          (_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
+          (_model == CPU_MODEL_BROADWELL  && _stepping < 4)) {
+        if (!UnlockExperimentalVMOptions) {
+          vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
+        } else {
+          warning("UseRTMLocking is only available as experimental option on this platform.");
+        }
+      }
+    }
     if (!FLAG_IS_CMDLINE(UseRTMLocking)) {
       // RTM locking should be used only for applications with
       // high lock contention. For now we do not use it by default.
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -276,7 +276,10 @@
     CPU_MODEL_WESTMERE_EX    = 0x2f,
     CPU_MODEL_SANDYBRIDGE    = 0x2a,
     CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
-    CPU_MODEL_IVYBRIDGE_EP   = 0x3a
+    CPU_MODEL_IVYBRIDGE_EP   = 0x3a,
+    CPU_MODEL_HASWELL_E3     = 0x3c,
+    CPU_MODEL_HASWELL_E7     = 0x3f,
+    CPU_MODEL_BROADWELL      = 0x3d
   } cpuExtendedFamily;
 
   // cpuid information block.  All info derived from executing cpuid with
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -135,11 +135,6 @@
       if (ForceTimeHighResolution)
         timeEndPeriod(1L);
 
-      // Workaround for issue when a custom launcher doesn't call
-      // DestroyJavaVM and NMT is trying to track memory when free is
-      // called from a static destructor
-      MemTracker::shutdown();
-
       break;
     default:
       break;
@@ -414,6 +409,8 @@
 
 LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
 
+extern jint volatile vm_getting_terminated;
+
 // Thread start routine for all new Java threads
 static unsigned __stdcall java_start(Thread* thread) {
   // Try to randomize the cache line index of hot stack frames.
@@ -435,9 +432,17 @@
     }
   }
 
+  // Diagnostic code to investigate JDK-6573254 (Part I)
+  unsigned res = 90115;  // non-java thread
+  if (thread->is_Java_thread()) {
+    JavaThread* java_thread = (JavaThread*)thread;
+    res = java_lang_Thread::is_daemon(java_thread->threadObj())
+          ? 70115        // java daemon thread
+          : 80115;       // java non-daemon thread
+  }
 
   // Install a win32 structured exception handler around every thread created
-  // by VM, so VM can genrate error dump when an exception occurred in non-
+  // by VM, so VM can generate error dump when an exception occurred in non-
   // Java thread (e.g. VM thread).
   __try {
      thread->run();
@@ -453,6 +458,11 @@
     Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
   }
 
+  // Diagnostic code to investigate JDK-6573254 (Part II)
+  if (OrderAccess::load_acquire(&vm_getting_terminated)) {
+    return res;
+  }
+
   return 0;
 }
 
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java	Wed Jul 05 20:00:07 2017 +0200
@@ -504,7 +504,7 @@
 
         super.init(includes, defines);
 
-        getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag()));
+        getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag(), get("PlatformName")));
         getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags());
    }
 }
@@ -619,7 +619,7 @@
 abstract class CompilerInterface {
     abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
     abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);
-    abstract Vector getDebugCompilerFlags(String opt);
+    abstract Vector getDebugCompilerFlags(String opt, String platformName);
     abstract Vector getDebugLinkerFlags();
     abstract void   getAdditionalNonKernelLinkerFlags(Vector rv);
     abstract Vector getProductCompilerFlags();
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Wed Jul 05 20:00:07 2017 +0200
@@ -357,7 +357,7 @@
     }
 
     @Override
-    Vector getDebugCompilerFlags(String opt) {
+    Vector getDebugCompilerFlags(String opt, String platformName) {
         Vector rv = new Vector();
 
         // Set /On option
@@ -369,6 +369,10 @@
         addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
         // Set /Oy- option
         addAttr(rv, "OmitFramePointers", "false");
+        // Set /homeparams for x64 debug builds
+        if(platformName.equals("x64")) {
+            addAttr(rv, "AdditionalOptions", "/homeparams");
+        }
 
         return rv;
     }
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Wed Jul 05 20:00:07 2017 +0200
@@ -284,7 +284,7 @@
 
    }
 
-   Vector getDebugCompilerFlags(String opt) {
+   Vector getDebugCompilerFlags(String opt, String platformName) {
       Vector rv = new Vector();
 
       getDebugCompilerFlags_common(opt, rv);
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC8.java	Wed Jul 05 20:00:07 2017 +0200
@@ -48,7 +48,7 @@
     }
 
 
-    Vector getDebugCompilerFlags(String opt) {
+    Vector getDebugCompilerFlags(String opt, String platformName) {
         Vector rv = new Vector();
 
         getDebugCompilerFlags_common(opt,rv);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -328,9 +328,11 @@
 void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
 
   const char* gen_name = "old";
+  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
 
   // Generation Counters - generation 1, 1 subspace
-  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
+  _gen_counters = new GenerationCounters(gen_name, 1, 1,
+      gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
 
   _space_counters = new GSpaceCounters(gen_name, 0,
                                        _virtual_space.reserved_size(),
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -34,8 +34,8 @@
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
 #include "gc_implementation/shared/gcTimer.hpp"
@@ -434,10 +434,6 @@
   }
 }
 
-bool ConcurrentMark::not_yet_marked(oop obj) const {
-  return _g1h->is_obj_ill(obj);
-}
-
 CMRootRegions::CMRootRegions() :
   _young_list(NULL), _cm(NULL), _scan_in_progress(false),
   _should_abort(false),  _next_survivor(NULL) { }
@@ -892,7 +888,16 @@
   }
 
   virtual bool doHeapRegion(HeapRegion* r) {
-    return _bitmap->getNextMarkedWordAddress(r->bottom(), r->end()) != r->end();
+    // This closure can be called concurrently to the mutator, so we must make sure
+    // that the result of the getNextMarkedWordAddress() call is compared to the
+    // value passed to it as limit to detect any found bits.
+    // We can use the region's orig_end() for the limit and the comparison value
+    // as it always contains the "real" end of the region that never changes and
+    // has no side effects.
+    // Due to the latter, there can also be no problem with the compiler generating
+    // reloads of the orig_end() call.
+    HeapWord* end = r->orig_end();
+    return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
   }
 };
 
@@ -1117,20 +1122,17 @@
     if (!_cm->has_aborted()) {
       do {
         double start_vtime_sec = os::elapsedVTime();
-        double start_time_sec = os::elapsedTime();
         double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
 
         the_task->do_marking_step(mark_step_duration_ms,
                                   true  /* do_termination */,
                                   false /* is_serial*/);
 
-        double end_time_sec = os::elapsedTime();
         double end_vtime_sec = os::elapsedVTime();
         double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
-        double elapsed_time_sec = end_time_sec - start_time_sec;
         _cm->clear_has_overflown();
 
-        bool ret = _cm->do_yield_check(worker_id);
+        _cm->do_yield_check(worker_id);
 
         jlong sleep_time_ms;
         if (!_cm->has_aborted() && the_task->has_aborted()) {
@@ -1140,17 +1142,6 @@
           os::sleep(Thread::current(), sleep_time_ms, false);
           SuspendibleThreadSet::join();
         }
-        double end_time2_sec = os::elapsedTime();
-        double elapsed_time2_sec = end_time2_sec - start_time_sec;
-
-#if 0
-          gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, "
-                                 "overhead %1.4lf",
-                                 elapsed_vtime_sec * 1000.0, (double) sleep_time_ms,
-                                 the_task->conc_overhead(os::elapsedTime()) * 8.0);
-          gclog_or_tty->print_cr("elapsed time %1.4lf ms, time 2: %1.4lf ms",
-                                 elapsed_time_sec * 1000.0, elapsed_time2_sec * 1000.0);
-#endif
       } while (!_cm->has_aborted() && the_task->has_aborted());
     }
     the_task->record_end_time();
@@ -1409,7 +1400,7 @@
   void set_bit_for_region(HeapRegion* hr) {
     assert(!hr->continuesHumongous(), "should have filtered those out");
 
-    BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
+    BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
     if (!hr->startsHumongous()) {
       // Normal (non-humongous) case: just set the bit.
       _region_bm->par_at_put(index, true);
@@ -1597,7 +1588,7 @@
       if (_verbose) {
         gclog_or_tty->print_cr("Region %u: marked bytes mismatch: "
                                "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
-                               hr->hrs_index(), exp_marked_bytes, act_marked_bytes);
+                               hr->hrm_index(), exp_marked_bytes, act_marked_bytes);
       }
       failures += 1;
     }
@@ -1606,7 +1597,7 @@
     // (which was just calculated) region bit maps.
     // We're not OK if the bit in the calculated expected region
     // bitmap is set and the bit in the actual region bitmap is not.
-    BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
+    BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
 
     bool expected = _exp_region_bm->at(index);
     bool actual = _region_bm->at(index);
@@ -1614,7 +1605,7 @@
       if (_verbose) {
         gclog_or_tty->print_cr("Region %u: region bitmap mismatch: "
                                "expected: %s, actual: %s",
-                               hr->hrs_index(),
+                               hr->hrm_index(),
                                BOOL_TO_STR(expected), BOOL_TO_STR(actual));
       }
       failures += 1;
@@ -1635,7 +1626,7 @@
         if (_verbose) {
           gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": "
                                  "expected: %s, actual: %s",
-                                 hr->hrs_index(), i,
+                                 hr->hrm_index(), i,
                                  BOOL_TO_STR(expected), BOOL_TO_STR(actual));
         }
         failures += 1;
@@ -2949,11 +2940,6 @@
   _nextMarkBitMap->clearRange(mr);
 }
 
-void ConcurrentMark::clearRangeBothBitmaps(MemRegion mr) {
-  clearRangePrevBitmap(mr);
-  clearRangeNextBitmap(mr);
-}
-
 HeapRegion*
 ConcurrentMark::claim_region(uint worker_id) {
   // "checkpoint" the finger
@@ -3256,7 +3242,7 @@
     assert(limit_idx <= end_idx, "or else use atomics");
 
     // Aggregate the "stripe" in the count data associated with hr.
-    uint hrs_index = hr->hrs_index();
+    uint hrm_index = hr->hrm_index();
     size_t marked_bytes = 0;
 
     for (uint i = 0; i < _max_worker_id; i += 1) {
@@ -3265,7 +3251,7 @@
 
       // Fetch the marked_bytes in this region for task i and
       // add it to the running total for this region.
-      marked_bytes += marked_bytes_array[hrs_index];
+      marked_bytes += marked_bytes_array[hrm_index];
 
       // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx)
       // into the global card bitmap.
@@ -3499,17 +3485,6 @@
   }
 }
 
-bool ConcurrentMark::containing_card_is_marked(void* p) {
-  size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1);
-  return _card_bm.at(offset >> CardTableModRefBS::card_shift);
-}
-
-bool ConcurrentMark::containing_cards_are_marked(void* start,
-                                                 void* last) {
-  return containing_card_is_marked(start) &&
-         containing_card_is_marked(last);
-}
-
 #ifndef PRODUCT
 // for debugging purposes
 void ConcurrentMark::print_finger() {
@@ -3762,7 +3737,7 @@
 
   if (_cm->verbose_medium()) {
       gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
-                        "scanned = %d%s, refs reached = %d%s",
+                        "scanned = "SIZE_FORMAT"%s, refs reached = "SIZE_FORMAT"%s",
                         _worker_id, last_interval_ms,
                         _words_scanned,
                         (_words_scanned >= _words_scanned_limit) ? " (*)" : "",
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -683,7 +683,9 @@
     return _task_queues->steal(worker_id, hash_seed, obj);
   }
 
-  ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev_bitmap_storage, G1RegionToSpaceMapper* next_bitmap_storage);
+  ConcurrentMark(G1CollectedHeap* g1h,
+                 G1RegionToSpaceMapper* prev_bitmap_storage,
+                 G1RegionToSpaceMapper* next_bitmap_storage);
   ~ConcurrentMark();
 
   ConcurrentMarkThread* cmThread() { return _cmThread; }
@@ -712,8 +714,10 @@
   // inconsistent) and always passing the size. hr is the region that
   // contains the object and it's passed optionally from callers who
   // might already have it (no point in recalculating it).
-  inline void grayRoot(oop obj, size_t word_size,
-                       uint worker_id, HeapRegion* hr = NULL);
+  inline void grayRoot(oop obj,
+                       size_t word_size,
+                       uint worker_id,
+                       HeapRegion* hr = NULL);
 
   // It iterates over the heap and for each object it comes across it
   // will dump the contents of its reference fields, as well as
@@ -734,7 +738,8 @@
   //   AND MARKED : indicates that an object is both explicitly and
   //   implicitly live (it should be one or the other, not both)
   void print_reachable(const char* str,
-                       VerifyOption vo, bool all) PRODUCT_RETURN;
+                       VerifyOption vo,
+                       bool all) PRODUCT_RETURN;
 
   // Clear the next marking bitmap (will be called concurrently).
   void clearNextBitmap();
@@ -771,12 +776,11 @@
   // this carefully!
   inline void markPrev(oop p);
 
-  // Clears marks for all objects in the given range, for the prev,
-  // next, or both bitmaps.  NB: the previous bitmap is usually
+  // Clears marks for all objects in the given range, for the prev or
+  // next bitmaps.  NB: the previous bitmap is usually
   // read-only, so use this carefully!
   void clearRangePrevBitmap(MemRegion mr);
   void clearRangeNextBitmap(MemRegion mr);
-  void clearRangeBothBitmaps(MemRegion mr);
 
   // Notify data structures that a GC has started.
   void note_start_of_gc() {
@@ -798,21 +802,6 @@
                            bool verify_thread_buffers,
                            bool verify_fingers) PRODUCT_RETURN;
 
-  bool isMarked(oop p) const {
-    assert(p != NULL && p->is_oop(), "expected an oop");
-    HeapWord* addr = (HeapWord*)p;
-    assert(addr >= _nextMarkBitMap->startWord() ||
-           addr < _nextMarkBitMap->endWord(), "in a region");
-
-    return _nextMarkBitMap->isMarked(addr);
-  }
-
-  inline bool not_yet_marked(oop p) const;
-
-  // XXX Debug code
-  bool containing_card_is_marked(void* p);
-  bool containing_cards_are_marked(void* start, void* last);
-
   bool isPrevMarked(oop p) const {
     assert(p != NULL && p->is_oop(), "expected an oop");
     HeapWord* addr = (HeapWord*)p;
@@ -898,7 +887,8 @@
   // marked_bytes array slot for the given HeapRegion.
   // Sets the bits in the given card bitmap that are associated with the
   // cards that are spanned by the memory region.
-  inline void count_region(MemRegion mr, HeapRegion* hr,
+  inline void count_region(MemRegion mr,
+                           HeapRegion* hr,
                            size_t* marked_bytes_array,
                            BitMap* task_card_bm);
 
@@ -906,56 +896,27 @@
   // data structures for the given worker id.
   inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id);
 
-  // Counts the given memory region in the task/worker counting
-  // data structures for the given worker id.
-  inline void count_region(MemRegion mr, uint worker_id);
-
   // Counts the given object in the given task/worker counting
   // data structures.
-  inline void count_object(oop obj, HeapRegion* hr,
+  inline void count_object(oop obj,
+                           HeapRegion* hr,
                            size_t* marked_bytes_array,
                            BitMap* task_card_bm);
 
-  // Counts the given object in the task/worker counting data
-  // structures for the given worker id.
-  inline void count_object(oop obj, HeapRegion* hr, uint worker_id);
-
   // Attempts to mark the given object and, if successful, counts
   // the object in the given task/worker counting structures.
-  inline bool par_mark_and_count(oop obj, HeapRegion* hr,
+  inline bool par_mark_and_count(oop obj,
+                                 HeapRegion* hr,
                                  size_t* marked_bytes_array,
                                  BitMap* task_card_bm);
 
   // Attempts to mark the given object and, if successful, counts
   // the object in the task/worker counting structures for the
   // given worker id.
-  inline bool par_mark_and_count(oop obj, size_t word_size,
-                                 HeapRegion* hr, uint worker_id);
-
-  // Attempts to mark the given object and, if successful, counts
-  // the object in the task/worker counting structures for the
-  // given worker id.
-  inline bool par_mark_and_count(oop obj, HeapRegion* hr, uint worker_id);
-
-  // Similar to the above routine but we don't know the heap region that
-  // contains the object to be marked/counted, which this routine looks up.
-  inline bool par_mark_and_count(oop obj, uint worker_id);
-
-  // Similar to the above routine but there are times when we cannot
-  // safely calculate the size of obj due to races and we, therefore,
-  // pass the size in as a parameter. It is the caller's responsibility
-  // to ensure that the size passed in for obj is valid.
-  inline bool par_mark_and_count(oop obj, size_t word_size, uint worker_id);
-
-  // Unconditionally mark the given object, and unconditionally count
-  // the object in the counting structures for worker id 0.
-  // Should *not* be called from parallel code.
-  inline bool mark_and_count(oop obj, HeapRegion* hr);
-
-  // Similar to the above routine but we don't know the heap region that
-  // contains the object to be marked/counted, which this routine looks up.
-  // Should *not* be called from parallel code.
-  inline bool mark_and_count(oop obj);
+  inline bool par_mark_and_count(oop obj,
+                                 size_t word_size,
+                                 HeapRegion* hr,
+                                 uint worker_id);
 
   // Returns true if initialization was successfully completed.
   bool completed_initialization() const {
@@ -1227,9 +1188,12 @@
     _finger = new_finger;
   }
 
-  CMTask(uint worker_id, ConcurrentMark *cm,
-         size_t* marked_bytes, BitMap* card_bm,
-         CMTaskQueue* task_queue, CMTaskQueueSet* task_queues);
+  CMTask(uint worker_id,
+         ConcurrentMark *cm,
+         size_t* marked_bytes,
+         BitMap* card_bm,
+         CMTaskQueue* task_queue,
+         CMTaskQueueSet* task_queues);
 
   // it prints statistics associated with this task
   void print_stats();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -86,7 +86,7 @@
   HeapWord* start = mr.start();
   HeapWord* end = mr.end();
   size_t region_size_bytes = mr.byte_size();
-  uint index = hr->hrs_index();
+  uint index = hr->hrm_index();
 
   assert(!hr->continuesHumongous(), "should not be HC region");
   assert(hr == g1h->heap_region_containing(start), "sanity");
@@ -125,14 +125,6 @@
   count_region(mr, hr, marked_bytes_array, task_card_bm);
 }
 
-// Counts the given memory region, which may be a single object, in the
-// task/worker counting data structures for the given worker id.
-inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
-  HeapWord* addr = mr.start();
-  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
-  count_region(mr, hr, worker_id);
-}
-
 // Counts the given object in the given task/worker counting data structures.
 inline void ConcurrentMark::count_object(oop obj,
                                          HeapRegion* hr,
@@ -142,17 +134,6 @@
   count_region(mr, hr, marked_bytes_array, task_card_bm);
 }
 
-// Counts the given object in the task/worker counting data
-// structures for the given worker id.
-inline void ConcurrentMark::count_object(oop obj,
-                                         HeapRegion* hr,
-                                         uint worker_id) {
-  size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
-  BitMap* task_card_bm = count_card_bitmap_for(worker_id);
-  HeapWord* addr = (HeapWord*) obj;
-  count_object(obj, hr, marked_bytes_array, task_card_bm);
-}
-
 // Attempts to mark the given object and, if successful, counts
 // the object in the given task/worker counting structures.
 inline bool ConcurrentMark::par_mark_and_count(oop obj,
@@ -184,63 +165,6 @@
   return false;
 }
 
-// Attempts to mark the given object and, if successful, counts
-// the object in the task/worker counting structures for the
-// given worker id.
-inline bool ConcurrentMark::par_mark_and_count(oop obj,
-                                               HeapRegion* hr,
-                                               uint worker_id) {
-  HeapWord* addr = (HeapWord*)obj;
-  if (_nextMarkBitMap->parMark(addr)) {
-    // Update the task specific count data for the object.
-    count_object(obj, hr, worker_id);
-    return true;
-  }
-  return false;
-}
-
-// As above - but we don't know the heap region containing the
-// object and so have to supply it.
-inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
-  HeapWord* addr = (HeapWord*)obj;
-  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
-  return par_mark_and_count(obj, hr, worker_id);
-}
-
-// Similar to the above routine but we already know the size, in words, of
-// the object that we wish to mark/count
-inline bool ConcurrentMark::par_mark_and_count(oop obj,
-                                               size_t word_size,
-                                               uint worker_id) {
-  HeapWord* addr = (HeapWord*)obj;
-  if (_nextMarkBitMap->parMark(addr)) {
-    // Update the task specific count data for the object.
-    MemRegion mr(addr, word_size);
-    count_region(mr, worker_id);
-    return true;
-  }
-  return false;
-}
-
-// Unconditionally mark the given object, and unconditionally count
-// the object in the counting structures for worker id 0.
-// Should *not* be called from parallel code.
-inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
-  HeapWord* addr = (HeapWord*)obj;
-  _nextMarkBitMap->mark(addr);
-  // Update the task specific count data for the object.
-  count_object(obj, hr, 0 /* worker_id */);
-  return true;
-}
-
-// As above - but we don't have the heap region containing the
-// object, so we have to supply it.
-inline bool ConcurrentMark::mark_and_count(oop obj) {
-  HeapWord* addr = (HeapWord*)obj;
-  HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
-  return mark_and_count(obj, hr);
-}
-
 inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
   HeapWord* start_addr = MAX2(startWord(), mr.start());
   HeapWord* end_addr = MIN2(endWord(), mr.end());
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -30,14 +30,7 @@
 #include "runtime/java.hpp"
 #include "services/memTracker.hpp"
 
-PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
-void G1BlockOffsetSharedArrayMappingChangedListener::on_commit(uint start_idx, size_t num_regions) {
-  // Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
-  // retrieve it here since this would cause firing of several asserts. The code
-  // executed after commit of a region already needs to do some re-initialization of
-  // the HeapRegion, so we combine that.
-}
 
 //////////////////////////////////////////////////////////////////////
 // G1BlockOffsetSharedArray
@@ -59,10 +52,10 @@
   if (TraceBlockOffsetTable) {
     gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
     gclog_or_tty->print_cr("  "
-                  "  rs.base(): " INTPTR_FORMAT
-                  "  rs.size(): " INTPTR_FORMAT
-                  "  rs end(): " INTPTR_FORMAT,
-                  bot_reserved.start(), bot_reserved.byte_size(), bot_reserved.end());
+                  "  rs.base(): " PTR_FORMAT
+                  "  rs.size(): " SIZE_FORMAT
+                  "  rs end(): " PTR_FORMAT,
+                  p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
   }
 }
 
@@ -72,26 +65,16 @@
   return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
 }
 
-void G1BlockOffsetSharedArray::set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
-  set_offset_array(index_for(left), index_for(right -1), offset);
-}
-
 //////////////////////////////////////////////////////////////////////
 // G1BlockOffsetArray
 //////////////////////////////////////////////////////////////////////
 
 G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
-                                       MemRegion mr, bool init_to_zero) :
+                                       MemRegion mr) :
   G1BlockOffsetTable(mr.start(), mr.end()),
   _unallocated_block(_bottom),
-  _array(array), _gsp(NULL),
-  _init_to_zero(init_to_zero) {
+  _array(array), _gsp(NULL) {
   assert(_bottom <= _end, "arguments out of order");
-  if (!_init_to_zero) {
-    // initialize cards to point back to mr.start()
-    set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
-    _array->set_offset_array(0, 0);  // set first card to 0
-  }
 }
 
 void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
@@ -181,93 +164,6 @@
   DEBUG_ONLY(check_all_cards(start_card, end_card);)
 }
 
-// The block [blk_start, blk_end) has been allocated;
-// adjust the block offset table to represent this information;
-// right-open interval: [blk_start, blk_end)
-void
-G1BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
-  mark_block(blk_start, blk_end);
-  allocated(blk_start, blk_end);
-}
-
-// Adjust BOT to show that a previously whole block has been split
-// into two.
-void G1BlockOffsetArray::split_block(HeapWord* blk, size_t blk_size,
-                                     size_t left_blk_size) {
-  // Verify that the BOT shows [blk, blk + blk_size) to be one block.
-  verify_single_block(blk, blk_size);
-  // Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
-  // is one single block.
-  mark_block(blk + left_blk_size, blk + blk_size);
-}
-
-
-// Action_mark - update the BOT for the block [blk_start, blk_end).
-//               Current typical use is for splitting a block.
-// Action_single - update the BOT for an allocation.
-// Action_verify - BOT verification.
-void G1BlockOffsetArray::do_block_internal(HeapWord* blk_start,
-                                           HeapWord* blk_end,
-                                           Action action) {
-  assert(Universe::heap()->is_in_reserved(blk_start),
-         "reference must be into the heap");
-  assert(Universe::heap()->is_in_reserved(blk_end-1),
-         "limit must be within the heap");
-  // This is optimized to make the test fast, assuming we only rarely
-  // cross boundaries.
-  uintptr_t end_ui = (uintptr_t)(blk_end - 1);
-  uintptr_t start_ui = (uintptr_t)blk_start;
-  // Calculate the last card boundary preceding end of blk
-  intptr_t boundary_before_end = (intptr_t)end_ui;
-  clear_bits(boundary_before_end, right_n_bits(LogN));
-  if (start_ui <= (uintptr_t)boundary_before_end) {
-    // blk starts at or crosses a boundary
-    // Calculate index of card on which blk begins
-    size_t    start_index = _array->index_for(blk_start);
-    // Index of card on which blk ends
-    size_t    end_index   = _array->index_for(blk_end - 1);
-    // Start address of card on which blk begins
-    HeapWord* boundary    = _array->address_for_index(start_index);
-    assert(boundary <= blk_start, "blk should start at or after boundary");
-    if (blk_start != boundary) {
-      // blk starts strictly after boundary
-      // adjust card boundary and start_index forward to next card
-      boundary += N_words;
-      start_index++;
-    }
-    assert(start_index <= end_index, "monotonicity of index_for()");
-    assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
-    switch (action) {
-      case Action_mark: {
-        if (init_to_zero()) {
-          _array->set_offset_array(start_index, boundary, blk_start);
-          break;
-        } // Else fall through to the next case
-      }
-      case Action_single: {
-        _array->set_offset_array(start_index, boundary, blk_start);
-        // We have finished marking the "offset card". We need to now
-        // mark the subsequent cards that this blk spans.
-        if (start_index < end_index) {
-          HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
-          HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
-          set_remainder_to_point_to_start(rem_st, rem_end);
-        }
-        break;
-      }
-      case Action_check: {
-        _array->check_offset_array(start_index, boundary, blk_start);
-        // We have finished checking the "offset card". We need to now
-        // check the subsequent cards that this blk spans.
-        check_all_cards(start_index + 1, end_index);
-        break;
-      }
-      default:
-        ShouldNotReachHere();
-    }
-  }
-}
-
 // The card-interval [start_card, end_card] is a closed interval; this
 // is an expensive check -- use with care and only under protection of
 // suitable flag.
@@ -306,25 +202,6 @@
   }
 }
 
-// The range [blk_start, blk_end) represents a single contiguous block
-// of storage; modify the block offset table to represent this
-// information; Right-open interval: [blk_start, blk_end)
-// NOTE: this method does _not_ adjust _unallocated_block.
-void
-G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
-  do_block_internal(blk_start, blk_end, Action_single);
-}
-
-// Mark the BOT such that if [blk_start, blk_end) straddles a card
-// boundary, the card following the first such boundary is marked
-// with the appropriate offset.
-// NOTE: this method does _not_ adjust _unallocated_block or
-// any cards subsequent to the first one.
-void
-G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {
-  do_block_internal(blk_start, blk_end, Action_mark);
-}
-
 HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
   assert(_bottom <= addr && addr < _end,
          "addr must be covered by this Array");
@@ -381,7 +258,7 @@
   assert(next_boundary <= _array->_end,
          err_msg("next_boundary is beyond the end of the covered region "
                  " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
-                 next_boundary, _array->_end));
+                 p2i(next_boundary), p2i(_array->_end)));
   if (addr >= gsp()->top()) return gsp()->top();
   while (next_boundary < addr) {
     while (n <= next_boundary) {
@@ -397,57 +274,13 @@
   return forward_to_block_containing_addr_const(q, n, addr);
 }
 
-HeapWord* G1BlockOffsetArray::block_start_careful(const void* addr) const {
-  assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
-
-  assert(_bottom <= addr && addr < _end,
-         "addr must be covered by this Array");
-  // Must read this exactly once because it can be modified by parallel
-  // allocation.
-  HeapWord* ub = _unallocated_block;
-  if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
-    assert(ub < _end, "tautology (see above)");
-    return ub;
-  }
-
-  // Otherwise, find the block start using the table, but taking
-  // care (cf block_start_unsafe() above) not to parse any objects/blocks
-  // on the cards themselves.
-  size_t index = _array->index_for(addr);
-  assert(_array->address_for_index(index) == addr,
-         "arg should be start of card");
-
-  HeapWord* q = (HeapWord*)addr;
-  uint offset;
-  do {
-    offset = _array->offset_array(index--);
-    q -= offset;
-  } while (offset == N_words);
-  assert(q <= addr, "block start should be to left of arg");
-  return q;
-}
-
 // Note that the committed size of the covered space may have changed,
 // so the table size might also wish to change.
 void G1BlockOffsetArray::resize(size_t new_word_size) {
   HeapWord* new_end = _bottom + new_word_size;
-  if (_end < new_end && !init_to_zero()) {
-    // verify that the old and new boundaries are also card boundaries
-    assert(_array->is_card_boundary(_end),
-           "_end not a card boundary");
-    assert(_array->is_card_boundary(new_end),
-           "new _end would not be a card boundary");
-    // set all the newly added cards
-    _array->set_offset_array(_end, new_end, N_words);
-  }
   _end = new_end;  // update _end
 }
 
-void G1BlockOffsetArray::set_region(MemRegion mr) {
-  _bottom = mr.start();
-  _end = mr.end();
-}
-
 //
 //              threshold_
 //              |   _index_
@@ -522,7 +355,7 @@
                   "blk_start: " PTR_FORMAT ", "
                   "boundary: " PTR_FORMAT,
                   (uint)_array->offset_array(orig_index),
-                  blk_start, boundary));
+                  p2i(blk_start), p2i(boundary)));
   for (size_t j = orig_index + 1; j <= end_index; j++) {
     assert(_array->offset_array(j) > 0 &&
            _array->offset_array(j) <=
@@ -556,9 +389,9 @@
                              "card addr: "PTR_FORMAT" BOT entry: %u "
                              "obj: "PTR_FORMAT" word size: "SIZE_FORMAT" "
                              "cards: ["SIZE_FORMAT","SIZE_FORMAT"]",
-                             block_start, card, card_addr,
+                             p2i(block_start), card, p2i(card_addr),
                              _array->offset_array(card),
-                             obj_start, word_size, first_card, last_card);
+                             p2i(obj_start), word_size, first_card, last_card);
       return false;
     }
   }
@@ -572,10 +405,10 @@
   size_t to_index = _array->index_for(_end);
   out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") "
                 "cards ["SIZE_FORMAT","SIZE_FORMAT")",
-                _bottom, _end, from_index, to_index);
+                p2i(_bottom), p2i(_end), from_index, to_index);
   for (size_t i = from_index; i < to_index; ++i) {
     out->print_cr("  entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u",
-                  i, _array->address_for_index(i),
+                  i, p2i(_array->address_for_index(i)),
                   (uint) _array->offset_array(i));
   }
 }
@@ -606,7 +439,7 @@
 G1BlockOffsetArrayContigSpace::
 G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array,
                               MemRegion mr) :
-  G1BlockOffsetArray(array, mr, true)
+  G1BlockOffsetArray(array, mr)
 {
   _next_offset_threshold = NULL;
   _next_offset_index = 0;
@@ -641,15 +474,6 @@
   return _next_offset_threshold;
 }
 
-void G1BlockOffsetArrayContigSpace::zero_bottom_entry() {
-  assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
-         "just checking");
-  size_t bottom_index = _array->index_for(_bottom);
-  assert(_array->address_for_index(bottom_index) == _bottom,
-         "Precondition of call");
-  _array->set_offset_array(bottom_index, 0);
-}
-
 void
 G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
   assert(new_top <= _end, "_end should have already been updated");
@@ -663,7 +487,7 @@
 void
 G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
   G1BlockOffsetArray::print_on(out);
-  out->print_cr("  next offset threshold: "PTR_FORMAT, _next_offset_threshold);
+  out->print_cr("  next offset threshold: "PTR_FORMAT, p2i(_next_offset_threshold));
   out->print_cr("  next offset index:     "SIZE_FORMAT, _next_offset_index);
 }
 #endif // !PRODUCT
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -109,7 +109,12 @@
 
 class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener {
  public:
-  virtual void on_commit(uint start_idx, size_t num_regions);
+  virtual void on_commit(uint start_idx, size_t num_regions) {
+    // Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
+    // retrieve it here since this would cause firing of several asserts. The code
+    // executed after commit of a region already needs to do some re-initialization of
+    // the HeapRegion, so we combine that.
+  }
 };
 
 // This implementation of "G1BlockOffsetTable" divides the covered region
@@ -153,8 +158,6 @@
   // For performance these have to devolve to array accesses in product builds.
   inline u_char offset_array(size_t index) const;
 
-  void set_offset_array(HeapWord* left, HeapWord* right, u_char offset);
-
   void set_offset_array_raw(size_t index, u_char offset) {
     _offset_array[index] = offset;
   }
@@ -165,8 +168,6 @@
 
   inline void set_offset_array(size_t left, size_t right, u_char offset);
 
-  inline void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const;
-
   bool is_card_boundary(HeapWord* p) const;
 
 public:
@@ -193,8 +194,6 @@
   // G1BlockOffsetTable(s) to initialize cards.
   G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage);
 
-  void set_bottom(HeapWord* new_bottom);
-
   // Return the appropriate index into "_offset_array" for "p".
   inline size_t index_for(const void* p) const;
   inline size_t index_for_raw(const void* p) const;
@@ -220,14 +219,6 @@
     LogN    = G1BlockOffsetSharedArray::LogN
   };
 
-  // The following enums are used by do_block_helper
-  enum Action {
-    Action_single,      // BOT records a single block (see single_block())
-    Action_mark,        // BOT marks the start of a block (see mark_block())
-    Action_check        // Check that BOT records block correctly
-                        // (see verify_single_block()).
-  };
-
   // This is the array, which can be shared by several BlockOffsetArray's
   // servicing different
   G1BlockOffsetSharedArray* _array;
@@ -235,10 +226,6 @@
   // The space that owns this subregion.
   G1OffsetTableContigSpace* _gsp;
 
-  // If true, array entries are initialized to 0; otherwise, they are
-  // initialized to point backwards to the beginning of the covered region.
-  bool _init_to_zero;
-
   // The portion [_unallocated_block, _sp.end()) of the space that
   // is a single block known not to contain any objects.
   // NOTE: See BlockOffsetArrayUseUnallocatedBlock flag.
@@ -253,9 +240,6 @@
   // that is closed: [start_index, end_index]
   void set_remainder_to_point_to_start_incl(size_t start, size_t end);
 
-  // A helper function for BOT adjustment/verification work
-  void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action);
-
 protected:
 
   G1OffsetTableContigSpace* gsp() const { return _gsp; }
@@ -303,11 +287,9 @@
 
 public:
   // The space may not have it's bottom and top set yet, which is why the
-  // region is passed as a parameter.  If "init_to_zero" is true, the
-  // elements of the array are initialized to zero.  Otherwise, they are
-  // initialized to point backwards to the beginning.
-  G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr,
-                     bool init_to_zero);
+  // region is passed as a parameter. The elements of the array are
+  // initialized to zero.
+  G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr);
 
   // Note: this ought to be part of the constructor, but that would require
   // "this" to be passed as a parameter to a member constructor for
@@ -315,114 +297,19 @@
   // This would be legal C++, but MS VC++ doesn't allow it.
   void set_space(G1OffsetTableContigSpace* sp);
 
-  // Resets the covered region to the given "mr".
-  void set_region(MemRegion mr);
-
   // Resets the covered region to one with the same _bottom as before but
   // the "new_word_size".
   void resize(size_t new_word_size);
 
-  // These must be guaranteed to work properly (i.e., do nothing)
-  // when "blk_start" ("blk" for second version) is "NULL".
-  virtual void alloc_block(HeapWord* blk_start, HeapWord* blk_end);
-  virtual void alloc_block(HeapWord* blk, size_t size) {
-    alloc_block(blk, blk + size);
-  }
-
-  // The following methods are useful and optimized for a
-  // general, non-contiguous space.
-
-  // Given a block [blk_start, blk_start + full_blk_size), and
-  // a left_blk_size < full_blk_size, adjust the BOT to show two
-  // blocks [blk_start, blk_start + left_blk_size) and
-  // [blk_start + left_blk_size, blk_start + full_blk_size).
-  // It is assumed (and verified in the non-product VM) that the
-  // BOT was correct for the original block.
-  void split_block(HeapWord* blk_start, size_t full_blk_size,
-                           size_t left_blk_size);
-
-  // Adjust the BOT to show that it has a single block in the
-  // range [blk_start, blk_start + size). All necessary BOT
-  // cards are adjusted, but _unallocated_block isn't.
-  void single_block(HeapWord* blk_start, HeapWord* blk_end);
-  void single_block(HeapWord* blk, size_t size) {
-    single_block(blk, blk + size);
-  }
-
-  // Adjust BOT to show that it has a block in the range
-  // [blk_start, blk_start + size). Only the first card
-  // of BOT is touched. It is assumed (and verified in the
-  // non-product VM) that the remaining cards of the block
-  // are correct.
-  void mark_block(HeapWord* blk_start, HeapWord* blk_end);
-  void mark_block(HeapWord* blk, size_t size) {
-    mark_block(blk, blk + size);
-  }
-
-  // Adjust _unallocated_block to indicate that a particular
-  // block has been newly allocated or freed. It is assumed (and
-  // verified in the non-product VM) that the BOT is correct for
-  // the given block.
-  inline void allocated(HeapWord* blk_start, HeapWord* blk_end) {
-    // Verify that the BOT shows [blk, blk + blk_size) to be one block.
-    verify_single_block(blk_start, blk_end);
-    if (BlockOffsetArrayUseUnallocatedBlock) {
-      _unallocated_block = MAX2(_unallocated_block, blk_end);
-    }
-  }
-
-  inline void allocated(HeapWord* blk, size_t size) {
-    allocated(blk, blk + size);
-  }
-
-  inline void freed(HeapWord* blk_start, HeapWord* blk_end);
-
-  inline void freed(HeapWord* blk, size_t size);
-
   virtual HeapWord* block_start_unsafe(const void* addr);
   virtual HeapWord* block_start_unsafe_const(const void* addr) const;
 
-  // Requires "addr" to be the start of a card and returns the
-  // start of the block that contains the given address.
-  HeapWord* block_start_careful(const void* addr) const;
-
-  // If true, initialize array slots with no allocated blocks to zero.
-  // Otherwise, make them point back to the front.
-  bool init_to_zero() { return _init_to_zero; }
-
-  // Verification & debugging - ensure that the offset table reflects the fact
-  // that the block [blk_start, blk_end) or [blk, blk + size) is a
-  // single block of storage. NOTE: can;t const this because of
-  // call to non-const do_block_internal() below.
-  inline void verify_single_block(HeapWord* blk_start, HeapWord* blk_end) {
-    if (VerifyBlockOffsetArray) {
-      do_block_internal(blk_start, blk_end, Action_check);
-    }
-  }
-
-  inline void verify_single_block(HeapWord* blk, size_t size) {
-    verify_single_block(blk, blk + size);
-  }
-
   // Used by region verification. Checks that the contents of the
   // BOT reflect that there's a single object that spans the address
   // range [obj_start, obj_start + word_size); returns true if this is
   // the case, returns false if it's not.
   bool verify_for_object(HeapWord* obj_start, size_t word_size) const;
 
-  // Verify that the given block is before _unallocated_block
-  inline void verify_not_unallocated(HeapWord* blk_start,
-                                     HeapWord* blk_end) const {
-    if (BlockOffsetArrayUseUnallocatedBlock) {
-      assert(blk_start < blk_end, "Block inconsistency?");
-      assert(blk_end <= _unallocated_block, "_unallocated_block problem");
-    }
-  }
-
-  inline void verify_not_unallocated(HeapWord* blk, size_t size) const {
-    verify_not_unallocated(blk, blk + size);
-  }
-
   void check_all_cards(size_t left_card, size_t right_card) const;
 
   virtual void print_on(outputStream* out) PRODUCT_RETURN;
@@ -445,14 +332,12 @@
                       blk_start, blk_end);
   }
 
-  // Variant of zero_bottom_entry that does not check for availability of the
+  // Zero out the entry for _bottom (offset will be zero). Does not check for availability of the
   // memory first.
   void zero_bottom_entry_raw();
   // Variant of initialize_threshold that does not check for availability of the
   // memory first.
   HeapWord* initialize_threshold_raw();
-  // Zero out the entry for _bottom (offset will be zero).
-  void zero_bottom_entry();
  public:
   G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -91,13 +91,6 @@
   }
 }
 
-void G1BlockOffsetSharedArray::check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
-  check_index(index, "index out of range");
-  assert(high >= low, "addresses out of order");
-  check_offset(pointer_delta(high, low), "offset too large");
-  assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
-}
-
 // Variant of index_for that does not check the index for validity.
 inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const {
   return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN;
@@ -193,28 +186,4 @@
   return q;
 }
 
-//////////////////////////////////////////////////////////////////////////
-// BlockOffsetArrayNonContigSpace inlines
-//////////////////////////////////////////////////////////////////////////
-inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) {
-  // Verify that the BOT shows [blk_start, blk_end) to be one block.
-  verify_single_block(blk_start, blk_end);
-  // adjust _unallocated_block upward or downward
-  // as appropriate
-  if (BlockOffsetArrayUseUnallocatedBlock) {
-    assert(_unallocated_block <= _end,
-           "Inconsistent value for _unallocated_block");
-    if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) {
-      // CMS-specific note: a block abutting _unallocated_block to
-      // its left is being freed, a new block is being added or
-      // we are resetting following a compaction
-      _unallocated_block = blk_start;
-    }
-  }
-}
-
-inline void G1BlockOffsetArray::freed(HeapWord* blk, size_t size) {
-  freed(blk, blk + size);
-}
-
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -532,9 +532,9 @@
       // again to allocate from it.
       append_secondary_free_list();
 
-      assert(_hrs.num_free_regions() > 0, "if the secondary_free_list was not "
+      assert(_hrm.num_free_regions() > 0, "if the secondary_free_list was not "
              "empty we should have moved at least one entry to the free_list");
-      HeapRegion* res = _hrs.allocate_free_region(is_old);
+      HeapRegion* res = _hrm.allocate_free_region(is_old);
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
                                "allocated "HR_FORMAT" from secondary_free_list",
@@ -575,7 +575,7 @@
     }
   }
 
-  res = _hrs.allocate_free_region(is_old);
+  res = _hrm.allocate_free_region(is_old);
 
   if (res == NULL) {
     if (G1ConcRegionFreeingVerbose) {
@@ -601,7 +601,7 @@
       // always expand the heap by an amount aligned to the heap
       // region size, the free list should in theory not be empty.
       // In either case allocate_free_region() will check for NULL.
-      res = _hrs.allocate_free_region(is_old);
+      res = _hrm.allocate_free_region(is_old);
     } else {
       _expand_heap_after_alloc_failure = false;
     }
@@ -613,7 +613,7 @@
 G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
                                                            uint num_regions,
                                                            size_t word_size) {
-  assert(first != G1_NO_HRS_INDEX, "pre-condition");
+  assert(first != G1_NO_HRM_INDEX, "pre-condition");
   assert(isHumongous(word_size), "word_size should be humongous");
   assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
 
@@ -751,7 +751,7 @@
 
   verify_region_sets_optional();
 
-  uint first = G1_NO_HRS_INDEX;
+  uint first = G1_NO_HRM_INDEX;
   uint obj_regions = (uint)(align_size_up_(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords);
 
   if (obj_regions == 1) {
@@ -760,7 +760,7 @@
     // later.
     HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */);
     if (hr != NULL) {
-      first = hr->hrs_index();
+      first = hr->hrm_index();
     }
   } else {
     // We can't allocate humongous regions spanning more than one region while
@@ -776,18 +776,18 @@
 
     // Policy: Try only empty regions (i.e. already committed first). Maybe we
     // are lucky enough to find some.
-    first = _hrs.find_contiguous_only_empty(obj_regions);
-    if (first != G1_NO_HRS_INDEX) {
-      _hrs.allocate_free_regions_starting_at(first, obj_regions);
-    }
-  }
-
-  if (first == G1_NO_HRS_INDEX) {
+    first = _hrm.find_contiguous_only_empty(obj_regions);
+    if (first != G1_NO_HRM_INDEX) {
+      _hrm.allocate_free_regions_starting_at(first, obj_regions);
+    }
+  }
+
+  if (first == G1_NO_HRM_INDEX) {
     // Policy: We could not find enough regions for the humongous object in the
     // free list. Look through the heap to find a mix of free and uncommitted regions.
     // If so, try expansion.
-    first = _hrs.find_contiguous_empty_or_unavailable(obj_regions);
-    if (first != G1_NO_HRS_INDEX) {
+    first = _hrm.find_contiguous_empty_or_unavailable(obj_regions);
+    if (first != G1_NO_HRM_INDEX) {
       // We found something. Make sure these regions are committed, i.e. expand
       // the heap. Alternatively we could do a defragmentation GC.
       ergo_verbose1(ErgoHeapSizing,
@@ -796,7 +796,7 @@
                     ergo_format_byte("allocation request"),
                     word_size * HeapWordSize);
 
-      _hrs.expand_at(first, obj_regions);
+      _hrm.expand_at(first, obj_regions);
       g1_policy()->record_new_heap_size(num_regions());
 
 #ifdef ASSERT
@@ -806,14 +806,14 @@
         assert(is_on_master_free_list(hr), "sanity");
       }
 #endif
-      _hrs.allocate_free_regions_starting_at(first, obj_regions);
+      _hrm.allocate_free_regions_starting_at(first, obj_regions);
     } else {
       // Policy: Potentially trigger a defragmentation GC.
     }
   }
 
   HeapWord* result = NULL;
-  if (first != G1_NO_HRS_INDEX) {
+  if (first != G1_NO_HRM_INDEX) {
     result = humongous_obj_allocate_initialize_regions(first, obj_regions, word_size);
     assert(result != NULL, "it should always return a valid result");
 
@@ -1248,7 +1248,7 @@
     : _hr_printer(hr_printer) { }
 };
 
-void G1CollectedHeap::print_hrs_post_compaction() {
+void G1CollectedHeap::print_hrm_post_compaction() {
   PostCompactionPrinterClosure cl(hr_printer());
   heap_region_iterate(&cl);
 }
@@ -1417,7 +1417,7 @@
         // that all the COMMIT / UNCOMMIT events are generated before
         // the end GC event.
 
-        print_hrs_post_compaction();
+        print_hrm_post_compaction();
         _hr_printer.end_gc(true /* full */, (size_t) total_collections());
       }
 
@@ -1490,7 +1490,7 @@
       // Update the number of full collections that have been completed.
       increment_old_marking_cycles_completed(false /* concurrent */);
 
-      _hrs.verify_optional();
+      _hrm.verify_optional();
       verify_region_sets_optional();
 
       verify_after_gc();
@@ -1734,7 +1734,7 @@
                 ergo_format_byte("allocation request"),
                 word_size * HeapWordSize);
   if (expand(expand_bytes)) {
-    _hrs.verify_optional();
+    _hrm.verify_optional();
     verify_region_sets_optional();
     return attempt_allocation_at_safepoint(word_size,
                                  false /* expect_null_mutator_alloc_region */);
@@ -1762,7 +1762,7 @@
   uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
   assert(regions_to_expand > 0, "Must expand by at least one region");
 
-  uint expanded_by = _hrs.expand_by(regions_to_expand);
+  uint expanded_by = _hrm.expand_by(regions_to_expand);
 
   if (expanded_by > 0) {
     size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes;
@@ -1775,7 +1775,7 @@
     // The expansion of the virtual storage space was unsuccessful.
     // Let's see if it was because we ran out of swap.
     if (G1ExitOnExpansionFailure &&
-        _hrs.available() >= regions_to_expand) {
+        _hrm.available() >= regions_to_expand) {
       // We had head room...
       vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion");
     }
@@ -1790,7 +1790,7 @@
                                          HeapRegion::GrainBytes);
   uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes);
 
-  uint num_regions_removed = _hrs.shrink_by(num_regions_to_remove);
+  uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove);
   size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes;
 
   ergo_verbose3(ErgoHeapSizing,
@@ -1823,7 +1823,7 @@
   shrink_helper(shrink_bytes);
   rebuild_region_sets(true /* free_list_only */);
 
-  _hrs.verify_optional();
+  _hrm.verify_optional();
   verify_region_sets_optional();
 }
 
@@ -1867,6 +1867,7 @@
   _old_marking_cycles_started(0),
   _old_marking_cycles_completed(0),
   _concurrent_cycle_started(false),
+  _heap_summary_sent(false),
   _in_cset_fast_test(),
   _dirty_cards_region_list(NULL),
   _worker_cset_start_region(NULL),
@@ -2032,7 +2033,7 @@
                                          CMBitMap::mark_distance(),
                                          mtGC);
 
-  _hrs.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
+  _hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
   g1_barrier_set()->initialize(cardtable_storage);
    // Do later initialization work for concurrent refinement.
   _cg1r->init(card_counts_storage);
@@ -2053,8 +2054,8 @@
 
   _g1h = this;
 
-  _in_cset_fast_test.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes);
-  _humongous_is_live.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes);
+  _in_cset_fast_test.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
+  _humongous_is_live.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
 
   // Create the ConcurrentMark data structure and thread.
   // (Must do this late, so that "max_regions" is defined.)
@@ -2115,7 +2116,7 @@
 
   // Here we allocate the dummy HeapRegion that is required by the
   // G1AllocRegion class.
-  HeapRegion* dummy_region = _hrs.get_dummy_region();
+  HeapRegion* dummy_region = _hrm.get_dummy_region();
 
   // We'll re-use the same region whether the alloc region will
   // require BOT updates or not and, if it doesn't, then a non-young
@@ -2232,14 +2233,14 @@
 }
 
 size_t G1CollectedHeap::capacity() const {
-  return _hrs.length() * HeapRegion::GrainBytes;
+  return _hrm.length() * HeapRegion::GrainBytes;
 }
 
 void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
   assert(!hr->continuesHumongous(), "pre-condition");
   hr->reset_gc_time_stamp();
   if (hr->startsHumongous()) {
-    uint first_index = hr->hrs_index() + 1;
+    uint first_index = hr->hrm_index() + 1;
     uint last_index = hr->last_hc_index();
     for (uint i = first_index; i < last_index; i += 1) {
       HeapRegion* chr = region_at(i);
@@ -2445,13 +2446,24 @@
     _gc_timer_cm->register_gc_end();
     _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
 
+    // Clear state variables to prepare for the next concurrent cycle.
     _concurrent_cycle_started = false;
+    _heap_summary_sent = false;
   }
 }
 
 void G1CollectedHeap::trace_heap_after_concurrent_cycle() {
   if (_concurrent_cycle_started) {
-    trace_heap_after_gc(_gc_tracer_cm);
+    // This function can be called when:
+    //  the cleanup pause is run
+    //  the concurrent cycle is aborted before the cleanup pause.
+    //  the concurrent cycle is aborted after the cleanup pause,
+    //   but before the concurrent cycle end has been registered.
+    // Make sure that we only send the heap information once.
+    if (!_heap_summary_sent) {
+      trace_heap_after_gc(_gc_tracer_cm);
+      _heap_summary_sent = true;
+    }
   }
 }
 
@@ -2537,7 +2549,7 @@
 }
 
 bool G1CollectedHeap::is_in(const void* p) const {
-  if (_hrs.reserved().contains(p)) {
+  if (_hrm.reserved().contains(p)) {
     // Given that we know that p is in the reserved space,
     // heap_region_containing_raw() should successfully
     // return the containing region.
@@ -2551,7 +2563,7 @@
 #ifdef ASSERT
 bool G1CollectedHeap::is_in_exact(const void* p) const {
   bool contains = reserved_region().contains(p);
-  bool available = _hrs.is_available(addr_to_region((HeapWord*)p));
+  bool available = _hrm.is_available(addr_to_region((HeapWord*)p));
   if (contains && available) {
     return true;
   } else {
@@ -2618,7 +2630,7 @@
 }
 
 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
-  _hrs.iterate(cl);
+  _hrm.iterate(cl);
 }
 
 void
@@ -2626,7 +2638,7 @@
                                                  uint worker_id,
                                                  uint num_workers,
                                                  jint claim_value) const {
-  _hrs.par_iterate(cl, worker_id, num_workers, claim_value);
+  _hrm.par_iterate(cl, worker_id, num_workers, claim_value);
 }
 
 class ResetClaimValuesClosure: public HeapRegionClosure {
@@ -2846,9 +2858,9 @@
 }
 
 HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const {
-  HeapRegion* result = _hrs.next_region_in_heap(from);
+  HeapRegion* result = _hrm.next_region_in_heap(from);
   while (result != NULL && result->isHumongous()) {
-    result = _hrs.next_region_in_heap(result);
+    result = _hrm.next_region_in_heap(result);
   }
   return result;
 }
@@ -2908,7 +2920,7 @@
 }
 
 size_t G1CollectedHeap::max_capacity() const {
-  return _hrs.reserved().byte_size();
+  return _hrm.reserved().byte_size();
 }
 
 jlong G1CollectedHeap::millis_since_last_gc() {
@@ -3437,9 +3449,9 @@
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
             capacity()/K, used_unlocked()/K);
   st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
-            _hrs.reserved().start(),
-            _hrs.reserved().start() + _hrs.length() + HeapRegion::GrainWords,
-            _hrs.reserved().end());
+            _hrm.reserved().start(),
+            _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
+            _hrm.reserved().end());
   st->cr();
   st->print("  region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
   uint young_regions = _young_list->length();
@@ -3682,7 +3694,7 @@
     }
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-    uint region_idx = r->hrs_index();
+    uint region_idx = r->hrm_index();
     bool is_candidate = !g1h->humongous_region_is_always_live(region_idx);
     // Is_candidate already filters out humongous regions with some remembered set.
     // This will not lead to humongous object that we mistakenly keep alive because
@@ -4205,7 +4217,7 @@
     // output from the concurrent mark thread interfering with this
     // logging output either.
 
-    _hrs.verify_optional();
+    _hrm.verify_optional();
     verify_region_sets_optional();
 
     TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
@@ -6024,7 +6036,7 @@
                                   bool locked) {
   assert(!hr->isHumongous(), "this is only for non-humongous regions");
   assert(!hr->is_empty(), "the region should not be empty");
-  assert(_hrs.is_available(hr->hrs_index()), "region should be committed");
+  assert(_hrm.is_available(hr->hrm_index()), "region should be committed");
   assert(free_list != NULL, "pre-condition");
 
   if (G1VerifyBitmaps) {
@@ -6055,7 +6067,7 @@
   hr->set_notHumongous();
   free_region(hr, free_list, par);
 
-  uint i = hr->hrs_index() + 1;
+  uint i = hr->hrm_index() + 1;
   while (i < last_index) {
     HeapRegion* curr_hr = region_at(i);
     assert(curr_hr->continuesHumongous(), "invariant");
@@ -6079,7 +6091,7 @@
   assert(list != NULL, "list can't be null");
   if (!list->is_empty()) {
     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
-    _hrs.insert_list_into_free_list(list);
+    _hrm.insert_list_into_free_list(list);
   }
 }
 
@@ -6448,7 +6460,7 @@
     // While this cleanup is not strictly necessary to be done (or done instantly),
     // given that their occurrence is very low, this saves us this additional
     // complexity.
-    uint region_idx = r->hrs_index();
+    uint region_idx = r->hrm_index();
     if (g1h->humongous_is_live(region_idx) ||
         g1h->humongous_region_is_always_live(region_idx)) {
 
@@ -6687,22 +6699,22 @@
     // this is that during a full GC string deduplication needs to know if
     // a collected region was young or old when the full GC was initiated.
   }
-  _hrs.remove_all_free_regions();
+  _hrm.remove_all_free_regions();
 }
 
 class RebuildRegionSetsClosure : public HeapRegionClosure {
 private:
   bool            _free_list_only;
   HeapRegionSet*   _old_set;
-  HeapRegionSeq*   _hrs;
+  HeapRegionManager*   _hrm;
   size_t          _total_used;
 
 public:
   RebuildRegionSetsClosure(bool free_list_only,
-                           HeapRegionSet* old_set, HeapRegionSeq* hrs) :
+                           HeapRegionSet* old_set, HeapRegionManager* hrm) :
     _free_list_only(free_list_only),
-    _old_set(old_set), _hrs(hrs), _total_used(0) {
-    assert(_hrs->num_free_regions() == 0, "pre-condition");
+    _old_set(old_set), _hrm(hrm), _total_used(0) {
+    assert(_hrm->num_free_regions() == 0, "pre-condition");
     if (!free_list_only) {
       assert(_old_set->is_empty(), "pre-condition");
     }
@@ -6715,7 +6727,7 @@
 
     if (r->is_empty()) {
       // Add free regions to the free list
-      _hrs->insert_into_free_list(r);
+      _hrm->insert_into_free_list(r);
     } else if (!_free_list_only) {
       assert(!r->is_young(), "we should not come across young regions");
 
@@ -6743,7 +6755,7 @@
     _young_list->empty_list();
   }
 
-  RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrs);
+  RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrm);
   heap_region_iterate(&cl);
 
   if (!free_list_only) {
@@ -6933,7 +6945,7 @@
 private:
   HeapRegionSet*   _old_set;
   HeapRegionSet*   _humongous_set;
-  HeapRegionSeq*   _hrs;
+  HeapRegionManager*   _hrm;
 
 public:
   HeapRegionSetCount _old_count;
@@ -6942,8 +6954,8 @@
 
   VerifyRegionListsClosure(HeapRegionSet* old_set,
                            HeapRegionSet* humongous_set,
-                           HeapRegionSeq* hrs) :
-    _old_set(old_set), _humongous_set(humongous_set), _hrs(hrs),
+                           HeapRegionManager* hrm) :
+    _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
     _old_count(), _humongous_count(), _free_count(){ }
 
   bool doHeapRegion(HeapRegion* hr) {
@@ -6954,19 +6966,19 @@
     if (hr->is_young()) {
       // TODO
     } else if (hr->startsHumongous()) {
-      assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrs_index()));
+      assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrm_index()));
       _humongous_count.increment(1u, hr->capacity());
     } else if (hr->is_empty()) {
-      assert(_hrs->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrs_index()));
+      assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index()));
       _free_count.increment(1u, hr->capacity());
     } else {
-      assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrs_index()));
+      assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index()));
       _old_count.increment(1u, hr->capacity());
     }
     return false;
   }
 
-  void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionSeq* free_list) {
+  void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
     guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length()));
     guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
         old_set->total_capacity_bytes(), _old_count.capacity()));
@@ -6985,7 +6997,7 @@
   assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
 
   // First, check the explicit lists.
-  _hrs.verify();
+  _hrm.verify();
   {
     // Given that a concurrent operation might be adding regions to
     // the secondary free list we have to take the lock before
@@ -7016,9 +7028,9 @@
   // Finally, make sure that the region accounting in the lists is
   // consistent with what we see in the heap.
 
-  VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrs);
+  VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrm);
   heap_region_iterate(&cl);
-  cl.verify_counts(&_old_set, &_humongous_set, &_hrs);
+  cl.verify_counts(&_old_set, &_humongous_set, &_hrm);
 }
 
 // Optimized nmethod scanning
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -33,7 +33,7 @@
 #include "gc_implementation/g1/g1MonitoringSupport.hpp"
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
 #include "gc_implementation/g1/g1YCTypes.hpp"
-#include "gc_implementation/g1/heapRegionSeq.hpp"
+#include "gc_implementation/g1/heapRegionManager.hpp"
 #include "gc_implementation/g1/heapRegionSet.hpp"
 #include "gc_implementation/shared/hSpaceCounters.hpp"
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
@@ -291,7 +291,7 @@
   G1RegionMappingChangedListener _listener;
 
   // The sequence of all heap regions in the heap.
-  HeapRegionSeq _hrs;
+  HeapRegionManager _hrm;
 
   // Alloc region used to satisfy mutator allocation requests.
   MutatorAllocRegion _mutator_alloc_region;
@@ -415,6 +415,7 @@
   volatile unsigned int _old_marking_cycles_completed;
 
   bool _concurrent_cycle_started;
+  bool _heap_summary_sent;
 
   // This is a non-product method that is helpful for testing. It is
   // called at the end of a GC and artificially expands the heap by
@@ -429,7 +430,7 @@
 
   // If the HR printer is active, dump the state of the regions in the
   // heap after a compaction.
-  void print_hrs_post_compaction();
+  void print_hrm_post_compaction();
 
   double verify(bool guard, const char* msg);
   void verify_before_gc();
@@ -715,7 +716,7 @@
   // We register a region with the fast "in collection set" test. We
   // simply set to true the array slot corresponding to this region.
   void register_region_with_in_cset_fast_test(HeapRegion* r) {
-    _in_cset_fast_test.set_in_cset(r->hrs_index());
+    _in_cset_fast_test.set_in_cset(r->hrm_index());
   }
 
   // This is a fast test on whether a reference points into the
@@ -1171,17 +1172,17 @@
   // But G1CollectedHeap doesn't yet support this.
 
   virtual bool is_maximal_no_gc() const {
-    return _hrs.available() == 0;
+    return _hrm.available() == 0;
   }
 
   // The current number of regions in the heap.
-  uint num_regions() const { return _hrs.length(); }
+  uint num_regions() const { return _hrm.length(); }
 
   // The max number of regions in the heap.
-  uint max_regions() const { return _hrs.max_length(); }
+  uint max_regions() const { return _hrm.max_length(); }
 
   // The number of regions that are completely free.
-  uint num_free_regions() const { return _hrs.num_free_regions(); }
+  uint num_free_regions() const { return _hrm.num_free_regions(); }
 
   // The number of regions that are not completely free.
   uint num_used_regions() const { return num_regions() - num_free_regions(); }
@@ -1233,7 +1234,7 @@
 
 #ifdef ASSERT
   bool is_on_master_free_list(HeapRegion* hr) {
-    return _hrs.is_free(hr);
+    return _hrm.is_free(hr);
   }
 #endif // ASSERT
 
@@ -1245,7 +1246,7 @@
   }
 
   void append_secondary_free_list() {
-    _hrs.insert_list_into_free_list(&_secondary_free_list);
+    _hrm.insert_list_into_free_list(&_secondary_free_list);
   }
 
   void append_secondary_free_list_if_not_empty_with_lock() {
@@ -1356,13 +1357,13 @@
   // Return "TRUE" iff the given object address is in the reserved
   // region of g1.
   bool is_in_g1_reserved(const void* p) const {
-    return _hrs.reserved().contains(p);
+    return _hrm.reserved().contains(p);
   }
 
   // Returns a MemRegion that corresponds to the space that has been
   // reserved for the heap
   MemRegion g1_reserved() const {
-    return _hrs.reserved();
+    return _hrm.reserved();
   }
 
   virtual bool is_in_closed_subset(const void* p) const;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -30,15 +30,15 @@
 #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/taskqueue.hpp"
 
 // Inline functions for G1CollectedHeap
 
 // Return the region with the given index. It assumes the index is valid.
-inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at(index); }
+inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
 
 inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
   assert(is_in_reserved(addr),
@@ -48,7 +48,7 @@
 }
 
 inline HeapWord* G1CollectedHeap::bottom_addr_for_region(uint index) const {
-  return _hrs.reserved().start() + index * HeapRegion::GrainWords;
+  return _hrm.reserved().start() + index * HeapRegion::GrainWords;
 }
 
 template <class T>
@@ -57,7 +57,7 @@
   assert(is_in_g1_reserved((const void*) addr),
       err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")",
           p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end())));
-  return _hrs.addr_to_region((HeapWord*) addr);
+  return _hrm.addr_to_region((HeapWord*) addr);
 }
 
 template <class T>
@@ -87,7 +87,7 @@
 }
 
 inline bool G1CollectedHeap::obj_in_cs(oop obj) {
-  HeapRegion* r = _hrs.addr_to_region((HeapWord*) obj);
+  HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj);
   return r != NULL && r->in_collection_set();
 }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -32,7 +32,7 @@
 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "memory/iterator.hpp"
 #include "oops/oop.inline.hpp"
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -29,7 +29,7 @@
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/shared/liveRange.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.hpp"
@@ -322,34 +322,11 @@
   return false;
 }
 
-HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) {
-  HeapWord* low = addr;
-  HeapWord* high = end();
-  while (low < high) {
-    size_t diff = pointer_delta(high, low);
-    // Must add one below to bias toward the high amount.  Otherwise, if
-  // "high" were at the desired value, and "low" were one less, we
-    // would not converge on "high".  This is not symmetric, because
-    // we set "high" to a block start, which might be the right one,
-    // which we don't do for "low".
-    HeapWord* middle = low + (diff+1)/2;
-    if (middle == high) return high;
-    HeapWord* mid_bs = block_start_careful(middle);
-    if (mid_bs < addr) {
-      low = middle;
-    } else {
-      high = mid_bs;
-    }
-  }
-  assert(low == high && low >= addr, "Didn't work.");
-  return low;
-}
-
-HeapRegion::HeapRegion(uint hrs_index,
+HeapRegion::HeapRegion(uint hrm_index,
                        G1BlockOffsetSharedArray* sharedOffsetArray,
                        MemRegion mr) :
     G1OffsetTableContigSpace(sharedOffsetArray, mr),
-    _hrs_index(hrs_index),
+    _hrm_index(hrm_index),
     _humongous_type(NotHumongous), _humongous_start_region(NULL),
     _in_collection_set(false),
     _next_in_special_set(NULL), _orig_end(NULL),
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -54,15 +54,15 @@
 
 #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
 #define HR_FORMAT_PARAMS(_hr_) \
-                (_hr_)->hrs_index(), \
+                (_hr_)->hrm_index(), \
                 (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
                 (_hr_)->startsHumongous() ? "HS" : \
                 (_hr_)->continuesHumongous() ? "HC" : \
                 !(_hr_)->is_empty() ? "O" : "F", \
                 p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end())
 
-// sentinel value for hrs_index
-#define G1_NO_HRS_INDEX ((uint) -1)
+// sentinel value for hrm_index
+#define G1_NO_HRM_INDEX ((uint) -1)
 
 // A dirty card to oop closure for heap regions. It
 // knows how to get the G1 heap and how to use the bitmap
@@ -206,10 +206,6 @@
     _offsets.reset_bot();
   }
 
-  void update_bot_for_object(HeapWord* start, size_t word_size) {
-    _offsets.alloc_block(start, word_size);
-  }
-
   void print_bot_on(outputStream* out) {
     _offsets.print_on(out);
   }
@@ -234,7 +230,7 @@
 
  protected:
   // The index of this region in the heap region sequence.
-  uint  _hrs_index;
+  uint  _hrm_index;
 
   HumongousType _humongous_type;
   // For a humongous region, region in which it starts.
@@ -330,7 +326,7 @@
   size_t _predicted_bytes_to_copy;
 
  public:
-  HeapRegion(uint hrs_index,
+  HeapRegion(uint hrm_index,
              G1BlockOffsetSharedArray* sharedOffsetArray,
              MemRegion mr);
 
@@ -385,9 +381,9 @@
   inline HeapWord* par_allocate_no_bot_updates(size_t word_size);
   inline HeapWord* allocate_no_bot_updates(size_t word_size);
 
-  // If this region is a member of a HeapRegionSeq, the index in that
+  // If this region is a member of a HeapRegionManager, the index in that
   // sequence, otherwise -1.
-  uint hrs_index() const { return _hrs_index; }
+  uint hrm_index() const { return _hrm_index; }
 
   // The number of bytes marked live in the region in the last marking phase.
   size_t marked_bytes()    { return _prev_marked_bytes; }
@@ -458,7 +454,7 @@
   // with this HS region.
   uint last_hc_index() const {
     assert(startsHumongous(), "don't call this otherwise");
-    return hrs_index() + region_num();
+    return hrm_index() + region_num();
   }
 
   // Same as Space::is_in_reserved, but will use the original size of the region.
@@ -570,7 +566,7 @@
   void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
   bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
 
-  HeapWord* orig_end() { return _orig_end; }
+  HeapWord* orig_end() const { return _orig_end; }
 
   // Reset HR stuff to default values.
   void hr_clear(bool par, bool clear_space, bool locked = false);
@@ -737,18 +733,6 @@
                                    bool filter_young,
                                    jbyte* card_ptr);
 
-  // A version of block start that is guaranteed to find *some* block
-  // boundary at or before "p", but does not object iteration, and may
-  // therefore be used safely when the heap is unparseable.
-  HeapWord* block_start_careful(const void* p) const {
-    return _offsets.block_start_careful(p);
-  }
-
-  // Requires that "addr" is within the region.  Returns the start of the
-  // first ("careful") block that starts at or after "addr", or else the
-  // "end" of the region if there is no such block.
-  HeapWord* next_block_start_careful(HeapWord* addr);
-
   size_t recorded_rs_length() const        { return _recorded_rs_length; }
   double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
   size_t predicted_bytes_to_copy() const   { return _predicted_bytes_to_copy; }
@@ -813,7 +797,7 @@
 // HeapRegionClosure is used for iterating over regions.
 // Terminates the iteration when the "doHeapRegion" method returns "true".
 class HeapRegionClosure : public StackObj {
-  friend class HeapRegionSeq;
+  friend class HeapRegionManager;
   friend class G1CollectedHeap;
 
   bool _complete;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2001, 2014, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/heapRegion.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
+#include "gc_implementation/g1/heapRegionSet.inline.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/concurrentG1Refine.hpp"
+#include "memory/allocation.hpp"
+
+void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
+                               G1RegionToSpaceMapper* prev_bitmap,
+                               G1RegionToSpaceMapper* next_bitmap,
+                               G1RegionToSpaceMapper* bot,
+                               G1RegionToSpaceMapper* cardtable,
+                               G1RegionToSpaceMapper* card_counts) {
+  _allocated_heapregions_length = 0;
+
+  _heap_mapper = heap_storage;
+
+  _prev_bitmap_mapper = prev_bitmap;
+  _next_bitmap_mapper = next_bitmap;
+
+  _bot_mapper = bot;
+  _cardtable_mapper = cardtable;
+
+  _card_counts_mapper = card_counts;
+
+  MemRegion reserved = heap_storage->reserved();
+  _regions.initialize(reserved.start(), reserved.end(), HeapRegion::GrainBytes);
+
+  _available_map.resize(_regions.length(), false);
+  _available_map.clear();
+}
+
+bool HeapRegionManager::is_available(uint region) const {
+  return _available_map.at(region);
+}
+
+#ifdef ASSERT
+bool HeapRegionManager::is_free(HeapRegion* hr) const {
+  return _free_list.contains(hr);
+}
+#endif
+
+HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
+  HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrm_index);
+  MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
+  assert(reserved().contains(mr), "invariant");
+  return new HeapRegion(hrm_index, G1CollectedHeap::heap()->bot_shared(), mr);
+}
+
+void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
+  guarantee(num_regions > 0, "Must commit more than zero regions");
+  guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
+
+  _num_committed += (uint)num_regions;
+
+  _heap_mapper->commit_regions(index, num_regions);
+
+  // Also commit auxiliary data
+  _prev_bitmap_mapper->commit_regions(index, num_regions);
+  _next_bitmap_mapper->commit_regions(index, num_regions);
+
+  _bot_mapper->commit_regions(index, num_regions);
+  _cardtable_mapper->commit_regions(index, num_regions);
+
+  _card_counts_mapper->commit_regions(index, num_regions);
+}
+
+void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
+  guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start));
+  guarantee(_num_committed >= num_regions, "pre-condition");
+
+  // Print before uncommitting.
+  if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
+    for (uint i = start; i < start + num_regions; i++) {
+      HeapRegion* hr = at(i);
+      G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end());
+    }
+  }
+
+  _num_committed -= (uint)num_regions;
+
+  _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range);
+  _heap_mapper->uncommit_regions(start, num_regions);
+
+  // Also uncommit auxiliary data
+  _prev_bitmap_mapper->uncommit_regions(start, num_regions);
+  _next_bitmap_mapper->uncommit_regions(start, num_regions);
+
+  _bot_mapper->uncommit_regions(start, num_regions);
+  _cardtable_mapper->uncommit_regions(start, num_regions);
+
+  _card_counts_mapper->uncommit_regions(start, num_regions);
+}
+
+void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
+  guarantee(num_regions > 0, "No point in calling this for zero regions");
+  commit_regions(start, num_regions);
+  for (uint i = start; i < start + num_regions; i++) {
+    if (_regions.get_by_index(i) == NULL) {
+      HeapRegion* new_hr = new_heap_region(i);
+      _regions.set_by_index(i, new_hr);
+      _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
+    }
+  }
+
+  _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
+
+  for (uint i = start; i < start + num_regions; i++) {
+    assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i));
+    HeapRegion* hr = at(i);
+    if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
+      G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end());
+    }
+    HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
+    MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
+
+    hr->initialize(mr);
+    insert_into_free_list(at(i));
+  }
+}
+
+uint HeapRegionManager::expand_by(uint num_regions) {
+  return expand_at(0, num_regions);
+}
+
+uint HeapRegionManager::expand_at(uint start, uint num_regions) {
+  if (num_regions == 0) {
+    return 0;
+  }
+
+  uint cur = start;
+  uint idx_last_found = 0;
+  uint num_last_found = 0;
+
+  uint expanded = 0;
+
+  while (expanded < num_regions &&
+         (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
+    uint to_expand = MIN2(num_regions - expanded, num_last_found);
+    make_regions_available(idx_last_found, to_expand);
+    expanded += to_expand;
+    cur = idx_last_found + num_last_found + 1;
+  }
+
+  verify_optional();
+  return expanded;
+}
+
+uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
+  uint found = 0;
+  size_t length_found = 0;
+  uint cur = 0;
+
+  while (length_found < num && cur < max_length()) {
+    HeapRegion* hr = _regions.get_by_index(cur);
+    if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
+      // This region is a potential candidate for allocation into.
+      length_found++;
+    } else {
+      // This region is not a candidate. The next region is the next possible one.
+      found = cur + 1;
+      length_found = 0;
+    }
+    cur++;
+  }
+
+  if (length_found == num) {
+    for (uint i = found; i < (found + num); i++) {
+      HeapRegion* hr = _regions.get_by_index(i);
+      // sanity check
+      guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
+                err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
+                        " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr)));
+    }
+    return found;
+  } else {
+    return G1_NO_HRM_INDEX;
+  }
+}
+
+HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
+  guarantee(r != NULL, "Start region must be a valid region");
+  guarantee(is_available(r->hrm_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrm_index()));
+  for (uint i = r->hrm_index() + 1; i < _allocated_heapregions_length; i++) {
+    HeapRegion* hr = _regions.get_by_index(i);
+    if (is_available(i)) {
+      return hr;
+    }
+  }
+  return NULL;
+}
+
+void HeapRegionManager::iterate(HeapRegionClosure* blk) const {
+  uint len = max_length();
+
+  for (uint i = 0; i < len; i++) {
+    if (!is_available(i)) {
+      continue;
+    }
+    guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i));
+    bool res = blk->doHeapRegion(at(i));
+    if (res) {
+      blk->incomplete();
+      return;
+    }
+  }
+}
+
+uint HeapRegionManager::find_unavailable_from_idx(uint start_idx, uint* res_idx) const {
+  guarantee(res_idx != NULL, "checking");
+  guarantee(start_idx <= (max_length() + 1), "checking");
+
+  uint num_regions = 0;
+
+  uint cur = start_idx;
+  while (cur < max_length() && is_available(cur)) {
+    cur++;
+  }
+  if (cur == max_length()) {
+    return num_regions;
+  }
+  *res_idx = cur;
+  while (cur < max_length() && !is_available(cur)) {
+    cur++;
+  }
+  num_regions = cur - *res_idx;
+#ifdef ASSERT
+  for (uint i = *res_idx; i < (*res_idx + num_regions); i++) {
+    assert(!is_available(i), "just checking");
+  }
+  assert(cur == max_length() || num_regions == 0 || is_available(cur),
+         err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
+#endif
+  return num_regions;
+}
+
+uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
+  return num_regions * worker_i / num_workers;
+}
+
+void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
+  const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
+
+  // Every worker will actually look at all regions, skipping over regions that
+  // are currently not committed.
+  // This also (potentially) iterates over regions newly allocated during GC. This
+  // is no problem except for some extra work.
+  for (uint count = 0; count < _allocated_heapregions_length; count++) {
+    const uint index = (start_index + count) % _allocated_heapregions_length;
+    assert(0 <= index && index < _allocated_heapregions_length, "sanity");
+    // Skip over unavailable regions
+    if (!is_available(index)) {
+      continue;
+    }
+    HeapRegion* r = _regions.get_by_index(index);
+    // We'll ignore "continues humongous" regions (we'll process them
+    // when we come across their corresponding "start humongous"
+    // region) and regions already claimed.
+    if (r->claim_value() == claim_value || r->continuesHumongous()) {
+      continue;
+    }
+    // OK, try to claim it
+    if (!r->claimHeapRegion(claim_value)) {
+      continue;
+    }
+    // Success!
+    if (r->startsHumongous()) {
+      // If the region is "starts humongous" we'll iterate over its
+      // "continues humongous" first; in fact we'll do them
+      // first. The order is important. In one case, calling the
+      // closure on the "starts humongous" region might de-allocate
+      // and clear all its "continues humongous" regions and, as a
+      // result, we might end up processing them twice. So, we'll do
+      // them first (note: most closures will ignore them anyway) and
+      // then we'll do the "starts humongous" region.
+      for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) {
+        HeapRegion* chr = _regions.get_by_index(ch_index);
+
+        assert(chr->continuesHumongous(), "Must be humongous region");
+        assert(chr->humongous_start_region() == r,
+               err_msg("Must work on humongous continuation of the original start region "
+                       PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
+        assert(chr->claim_value() != claim_value,
+               "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
+
+        bool claim_result = chr->claimHeapRegion(claim_value);
+        // We should always be able to claim it; no one else should
+        // be trying to claim this region.
+        guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object");
+
+        bool res2 = blk->doHeapRegion(chr);
+        if (res2) {
+          return;
+        }
+
+        // Right now, this holds (i.e., no closure that actually
+        // does something with "continues humongous" regions
+        // clears them). We might have to weaken it in the future,
+        // but let's leave these two asserts here for extra safety.
+        assert(chr->continuesHumongous(), "should still be the case");
+        assert(chr->humongous_start_region() == r, "sanity");
+      }
+    }
+
+    bool res = blk->doHeapRegion(r);
+    if (res) {
+      return;
+    }
+  }
+}
+
+uint HeapRegionManager::shrink_by(uint num_regions_to_remove) {
+  assert(length() > 0, "the region sequence should not be empty");
+  assert(length() <= _allocated_heapregions_length, "invariant");
+  assert(_allocated_heapregions_length > 0, "we should have at least one region committed");
+  assert(num_regions_to_remove < length(), "We should never remove all regions");
+
+  if (num_regions_to_remove == 0) {
+    return 0;
+  }
+
+  uint removed = 0;
+  uint cur = _allocated_heapregions_length - 1;
+  uint idx_last_found = 0;
+  uint num_last_found = 0;
+
+  while ((removed < num_regions_to_remove) &&
+      (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) {
+    uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found);
+
+    uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove);
+
+    cur -= num_last_found;
+    removed += to_remove;
+  }
+
+  verify_optional();
+
+  return removed;
+}
+
+uint HeapRegionManager::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const {
+  guarantee(start_idx < _allocated_heapregions_length, "checking");
+  guarantee(res_idx != NULL, "checking");
+
+  uint num_regions_found = 0;
+
+  jlong cur = start_idx;
+  while (cur != -1 && !(is_available(cur) && at(cur)->is_empty())) {
+    cur--;
+  }
+  if (cur == -1) {
+    return num_regions_found;
+  }
+  jlong old_cur = cur;
+  // cur indexes the first empty region
+  while (cur != -1 && is_available(cur) && at(cur)->is_empty()) {
+    cur--;
+  }
+  *res_idx = cur + 1;
+  num_regions_found = old_cur - cur;
+
+#ifdef ASSERT
+  for (uint i = *res_idx; i < (*res_idx + num_regions_found); i++) {
+    assert(at(i)->is_empty(), "just checking");
+  }
+#endif
+  return num_regions_found;
+}
+
+void HeapRegionManager::verify() {
+  guarantee(length() <= _allocated_heapregions_length,
+            err_msg("invariant: _length: %u _allocated_length: %u",
+                    length(), _allocated_heapregions_length));
+  guarantee(_allocated_heapregions_length <= max_length(),
+            err_msg("invariant: _allocated_length: %u _max_length: %u",
+                    _allocated_heapregions_length, max_length()));
+
+  bool prev_committed = true;
+  uint num_committed = 0;
+  HeapWord* prev_end = heap_bottom();
+  for (uint i = 0; i < _allocated_heapregions_length; i++) {
+    if (!is_available(i)) {
+      prev_committed = false;
+      continue;
+    }
+    num_committed++;
+    HeapRegion* hr = _regions.get_by_index(i);
+    guarantee(hr != NULL, err_msg("invariant: i: %u", i));
+    guarantee(!prev_committed || hr->bottom() == prev_end,
+              err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
+                      i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
+    guarantee(hr->hrm_index() == i,
+              err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index()));
+    // Asserts will fire if i is >= _length
+    HeapWord* addr = hr->bottom();
+    guarantee(addr_to_region(addr) == hr, "sanity");
+    // We cannot check whether the region is part of a particular set: at the time
+    // this method may be called, we have only completed allocation of the regions,
+    // but not put into a region set.
+    prev_committed = true;
+    if (hr->startsHumongous()) {
+      prev_end = hr->orig_end();
+    } else {
+      prev_end = hr->end();
+    }
+  }
+  for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
+    guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
+  }
+
+  guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed));
+  _free_list.verify();
+}
+
+#ifndef PRODUCT
+void HeapRegionManager::verify_optional() {
+  verify();
+}
+#endif // PRODUCT
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
+
+#include "gc_implementation/g1/g1BiasedArray.hpp"
+#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
+#include "gc_implementation/g1/heapRegionSet.hpp"
+
+class HeapRegion;
+class HeapRegionClosure;
+class FreeRegionList;
+
+class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
+ protected:
+  virtual HeapRegion* default_value() const { return NULL; }
+};
+
+// This class keeps track of the actual heap memory, auxiliary data
+// and its metadata (i.e., HeapRegion instances) and the list of free regions.
+//
+// This allows maximum flexibility for deciding what to commit or uncommit given
+// a request from outside.
+//
+// HeapRegions are kept in the _regions array in address order. A region's
+// index in the array corresponds to its index in the heap (i.e., 0 is the
+// region at the bottom of the heap, 1 is the one after it, etc.). Two
+// regions that are consecutive in the array should also be adjacent in the
+// address space (i.e., region(i).end() == region(i+1).bottom().
+//
+// We create a HeapRegion when we commit the region's address space
+// for the first time. When we uncommit the address space of a
+// region we retain the HeapRegion to be able to re-use it in the
+// future (in case we recommit it).
+//
+// We keep track of three lengths:
+//
+// * _num_committed (returned by length()) is the number of currently
+//   committed regions. These may not be contiguous.
+// * _allocated_heapregions_length (not exposed outside this class) is the
+//   number of regions+1 for which we have HeapRegions.
+// * max_length() returns the maximum number of regions the heap can have.
+//
+
+class HeapRegionManager: public CHeapObj<mtGC> {
+  friend class VMStructs;
+
+  G1HeapRegionTable _regions;
+
+  G1RegionToSpaceMapper* _heap_mapper;
+  G1RegionToSpaceMapper* _prev_bitmap_mapper;
+  G1RegionToSpaceMapper* _next_bitmap_mapper;
+  G1RegionToSpaceMapper* _bot_mapper;
+  G1RegionToSpaceMapper* _cardtable_mapper;
+  G1RegionToSpaceMapper* _card_counts_mapper;
+
+  FreeRegionList _free_list;
+
+  // Each bit in this bitmap indicates that the corresponding region is available
+  // for allocation.
+  BitMap _available_map;
+
+   // The number of regions committed in the heap.
+  uint _num_committed;
+
+  // Internal only. The highest heap region +1 we allocated a HeapRegion instance for.
+  uint _allocated_heapregions_length;
+
+  HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
+  HeapWord* heap_end() const {return _regions.end_address_mapped(); }
+
+  void make_regions_available(uint index, uint num_regions = 1);
+
+  // Pass down commit calls to the VirtualSpace.
+  void commit_regions(uint index, size_t num_regions = 1);
+  void uncommit_regions(uint index, size_t num_regions = 1);
+
+  // Notify other data structures about change in the heap layout.
+  void update_committed_space(HeapWord* old_end, HeapWord* new_end);
+  // Calculate the starting region for each worker during parallel iteration so
+  // that they do not all start from the same region.
+  uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
+
+  // Find a contiguous set of empty or uncommitted regions of length num and return
+  // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
+  // If only_empty is true, only empty regions are considered.
+  // Searches from bottom to top of the heap, doing a first-fit.
+  uint find_contiguous(size_t num, bool only_empty);
+  // Finds the next sequence of unavailable regions starting from start_idx. Returns the
+  // length of the sequence found. If this result is zero, no such sequence could be found,
+  // otherwise res_idx indicates the start index of these regions.
+  uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const;
+  // Finds the next sequence of empty regions starting from start_idx, going backwards in
+  // the heap. Returns the length of the sequence found. If this value is zero, no
+  // sequence could be found, otherwise res_idx contains the start index of this range.
+  uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const;
+  // Allocate a new HeapRegion for the given index.
+  HeapRegion* new_heap_region(uint hrm_index);
+#ifdef ASSERT
+public:
+  bool is_free(HeapRegion* hr) const;
+#endif
+  // Returns whether the given region is available for allocation.
+  bool is_available(uint region) const;
+
+ public:
+  // Empty constructor, we'll initialize it with the initialize() method.
+  HeapRegionManager() : _regions(), _heap_mapper(NULL), _num_committed(0),
+                    _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL),
+                    _allocated_heapregions_length(0), _available_map(),
+                    _free_list("Free list", new MasterFreeRegionListMtSafeChecker())
+  { }
+
+  void initialize(G1RegionToSpaceMapper* heap_storage,
+                  G1RegionToSpaceMapper* prev_bitmap,
+                  G1RegionToSpaceMapper* next_bitmap,
+                  G1RegionToSpaceMapper* bot,
+                  G1RegionToSpaceMapper* cardtable,
+                  G1RegionToSpaceMapper* card_counts);
+
+  // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
+  // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit
+  // the heap from the lowest address, this region (and its associated data
+  // structures) are available and we do not need to check further.
+  HeapRegion* get_dummy_region() { return new_heap_region(0); }
+
+  // Return the HeapRegion at the given index. Assume that the index
+  // is valid.
+  inline HeapRegion* at(uint index) const;
+
+  // If addr is within the committed space return its corresponding
+  // HeapRegion, otherwise return NULL.
+  inline HeapRegion* addr_to_region(HeapWord* addr) const;
+
+  // Insert the given region into the free region list.
+  inline void insert_into_free_list(HeapRegion* hr);
+
+  // Insert the given region list into the global free region list.
+  void insert_list_into_free_list(FreeRegionList* list) {
+    _free_list.add_ordered(list);
+  }
+
+  HeapRegion* allocate_free_region(bool is_old) {
+    HeapRegion* hr = _free_list.remove_region(is_old);
+
+    if (hr != NULL) {
+      assert(hr->next() == NULL, "Single region should not have next");
+      assert(is_available(hr->hrm_index()), "Must be committed");
+    }
+    return hr;
+  }
+
+  inline void allocate_free_regions_starting_at(uint first, uint num_regions);
+
+  // Remove all regions from the free list.
+  void remove_all_free_regions() {
+    _free_list.remove_all();
+  }
+
+  // Return the number of committed free regions in the heap.
+  uint num_free_regions() const {
+    return _free_list.length();
+  }
+
+  size_t total_capacity_bytes() const {
+    return num_free_regions() * HeapRegion::GrainBytes;
+  }
+
+  // Return the number of available (uncommitted) regions.
+  uint available() const { return max_length() - length(); }
+
+  // Return the number of regions that have been committed in the heap.
+  uint length() const { return _num_committed; }
+
+  // Return the maximum number of regions in the heap.
+  uint max_length() const { return (uint)_regions.length(); }
+
+  MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
+
+  // Expand the sequence to reflect that the heap has grown. Either create new
+  // HeapRegions, or re-use existing ones. Returns the number of regions the
+  // sequence was expanded by. If a HeapRegion allocation fails, the resulting
+  // number of regions might be smaller than what's desired.
+  uint expand_by(uint num_regions);
+
+  // Makes sure that the regions from start to start+num_regions-1 are available
+  // for allocation. Returns the number of regions that were committed to achieve
+  // this.
+  uint expand_at(uint start, uint num_regions);
+
+  // Find a contiguous set of empty regions of length num. Returns the start index of
+  // that set, or G1_NO_HRM_INDEX.
+  uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
+  // Find a contiguous set of empty or unavailable regions of length num. Returns the
+  // start index of that set, or G1_NO_HRM_INDEX.
+  uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
+
+  HeapRegion* next_region_in_heap(const HeapRegion* r) const;
+
+  // Apply blk->doHeapRegion() on all committed regions in address order,
+  // terminating the iteration early if doHeapRegion() returns true.
+  void iterate(HeapRegionClosure* blk) const;
+
+  void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const;
+
+  // Uncommit up to num_regions_to_remove regions that are completely free.
+  // Return the actual number of uncommitted regions.
+  uint shrink_by(uint num_regions_to_remove);
+
+  void verify();
+
+  // Do some sanity checking.
+  void verify_optional() PRODUCT_RETURN;
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionManager.inline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001, 2014, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
+
+#include "gc_implementation/g1/heapRegion.hpp"
+#include "gc_implementation/g1/heapRegionManager.hpp"
+#include "gc_implementation/g1/heapRegionSet.inline.hpp"
+
+inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
+  assert(addr < heap_end(),
+        err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end())));
+  assert(addr >= heap_bottom(),
+        err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
+
+  HeapRegion* hr = _regions.get_by_address(addr);
+  return hr;
+}
+
+inline HeapRegion* HeapRegionManager::at(uint index) const {
+  assert(is_available(index), "pre-condition");
+  HeapRegion* hr = _regions.get_by_index(index);
+  assert(hr != NULL, "sanity");
+  assert(hr->hrm_index() == index, "sanity");
+  return hr;
+}
+
+inline void HeapRegionManager::insert_into_free_list(HeapRegion* hr) {
+  _free_list.add_ordered(hr);
+}
+
+inline void HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) {
+  _free_list.remove_starting_at(at(first), num_regions);
+}
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -27,7 +27,7 @@
 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "memory/allocation.hpp"
 #include "memory/padded.inline.hpp"
 #include "memory/space.inline.hpp"
@@ -420,7 +420,7 @@
 }
 
 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
-  uint cur_hrs_ind = hr()->hrs_index();
+  uint cur_hrm_ind = hr()->hrm_index();
 
   if (G1TraceHeapRegionRememberedSet) {
     gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
@@ -435,10 +435,10 @@
   if (G1TraceHeapRegionRememberedSet) {
     gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
                   hr()->bottom(), from_card,
-                  FromCardCache::at((uint)tid, cur_hrs_ind));
+                  FromCardCache::at((uint)tid, cur_hrm_ind));
   }
 
-  if (FromCardCache::contains_or_replace((uint)tid, cur_hrs_ind, from_card)) {
+  if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) {
     if (G1TraceHeapRegionRememberedSet) {
       gclog_or_tty->print_cr("  from-card cache hit.");
     }
@@ -448,7 +448,7 @@
 
   // Note that this may be a continued H region.
   HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
-  RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index();
+  RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrm_index();
 
   // If the region is already coarsened, return.
   if (_coarse_map.at(from_hrs_ind)) {
@@ -495,7 +495,7 @@
         if (G1TraceHeapRegionRememberedSet) {
           gclog_or_tty->print_cr("   [tid %d] sparse table entry "
                         "overflow(f: %d, t: %u)",
-                        tid, from_hrs_ind, cur_hrs_ind);
+                        tid, from_hrs_ind, cur_hrm_ind);
         }
       }
 
@@ -607,9 +607,9 @@
   guarantee(max != NULL, "Since _n_fine_entries > 0");
 
   // Set the corresponding coarse bit.
-  size_t max_hrs_index = (size_t) max->hr()->hrs_index();
-  if (!_coarse_map.at(max_hrs_index)) {
-    _coarse_map.at_put(max_hrs_index, true);
+  size_t max_hrm_index = (size_t) max->hr()->hrm_index();
+  if (!_coarse_map.at(max_hrm_index)) {
+    _coarse_map.at_put(max_hrm_index, true);
     _n_coarse_entries++;
     if (G1TraceHeapRegionRememberedSet) {
       gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
@@ -633,7 +633,7 @@
                               BitMap* region_bm, BitMap* card_bm) {
   // First eliminated garbage regions from the coarse map.
   if (G1RSScrubVerbose) {
-    gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index());
+    gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
   }
 
   assert(_coarse_map.size() == region_bm->size(), "Precondition");
@@ -656,9 +656,9 @@
       // If the entire region is dead, eliminate.
       if (G1RSScrubVerbose) {
         gclog_or_tty->print_cr("     For other region %u:",
-                               cur->hr()->hrs_index());
+                               cur->hr()->hrm_index());
       }
-      if (!region_bm->at((size_t) cur->hr()->hrs_index())) {
+      if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
         *prev = nxt;
         cur->set_collision_list_next(NULL);
         _n_fine_entries--;
@@ -752,7 +752,7 @@
 }
 
 void OtherRegionsTable::clear_fcc() {
-  FromCardCache::clear(hr()->hrs_index());
+  FromCardCache::clear(hr()->hrm_index());
 }
 
 void OtherRegionsTable::clear() {
@@ -803,7 +803,7 @@
 
 bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
   HeapRegion* hr = _g1h->heap_region_containing_raw(from);
-  RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index();
+  RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index();
   // Is this region in the coarse map?
   if (_coarse_map.at(hr_ind)) return true;
 
@@ -840,7 +840,7 @@
 HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
                                    HeapRegion* hr)
   : _bosa(bosa),
-    _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrs_index()), true),
+    _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true),
     _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) {
   reset_for_par_iteration();
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 2001, 2014, 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.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc_implementation/g1/heapRegion.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
-#include "gc_implementation/g1/heapRegionSet.inline.hpp"
-#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
-#include "gc_implementation/g1/concurrentG1Refine.hpp"
-#include "memory/allocation.hpp"
-
-void HeapRegionSeq::initialize(G1RegionToSpaceMapper* heap_storage,
-                               G1RegionToSpaceMapper* prev_bitmap,
-                               G1RegionToSpaceMapper* next_bitmap,
-                               G1RegionToSpaceMapper* bot,
-                               G1RegionToSpaceMapper* cardtable,
-                               G1RegionToSpaceMapper* card_counts) {
-  _allocated_heapregions_length = 0;
-
-  _heap_mapper = heap_storage;
-
-  _prev_bitmap_mapper = prev_bitmap;
-  _next_bitmap_mapper = next_bitmap;
-
-  _bot_mapper = bot;
-  _cardtable_mapper = cardtable;
-
-  _card_counts_mapper = card_counts;
-
-  MemRegion reserved = heap_storage->reserved();
-  _regions.initialize(reserved.start(), reserved.end(), HeapRegion::GrainBytes);
-
-  _available_map.resize(_regions.length(), false);
-  _available_map.clear();
-}
-
-bool HeapRegionSeq::is_available(uint region) const {
-  return _available_map.at(region);
-}
-
-#ifdef ASSERT
-bool HeapRegionSeq::is_free(HeapRegion* hr) const {
-  return _free_list.contains(hr);
-}
-#endif
-
-HeapRegion* HeapRegionSeq::new_heap_region(uint hrs_index) {
-  HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrs_index);
-  MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
-  assert(reserved().contains(mr), "invariant");
-  return new HeapRegion(hrs_index, G1CollectedHeap::heap()->bot_shared(), mr);
-}
-
-void HeapRegionSeq::commit_regions(uint index, size_t num_regions) {
-  guarantee(num_regions > 0, "Must commit more than zero regions");
-  guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
-
-  _num_committed += (uint)num_regions;
-
-  _heap_mapper->commit_regions(index, num_regions);
-
-  // Also commit auxiliary data
-  _prev_bitmap_mapper->commit_regions(index, num_regions);
-  _next_bitmap_mapper->commit_regions(index, num_regions);
-
-  _bot_mapper->commit_regions(index, num_regions);
-  _cardtable_mapper->commit_regions(index, num_regions);
-
-  _card_counts_mapper->commit_regions(index, num_regions);
-}
-
-void HeapRegionSeq::uncommit_regions(uint start, size_t num_regions) {
-  guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start));
-  guarantee(_num_committed >= num_regions, "pre-condition");
-
-  // Print before uncommitting.
-  if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
-    for (uint i = start; i < start + num_regions; i++) {
-      HeapRegion* hr = at(i);
-      G1CollectedHeap::heap()->hr_printer()->uncommit(hr->bottom(), hr->end());
-    }
-  }
-
-  _num_committed -= (uint)num_regions;
-
-  _available_map.par_clear_range(start, start + num_regions, BitMap::unknown_range);
-  _heap_mapper->uncommit_regions(start, num_regions);
-
-  // Also uncommit auxiliary data
-  _prev_bitmap_mapper->uncommit_regions(start, num_regions);
-  _next_bitmap_mapper->uncommit_regions(start, num_regions);
-
-  _bot_mapper->uncommit_regions(start, num_regions);
-  _cardtable_mapper->uncommit_regions(start, num_regions);
-
-  _card_counts_mapper->uncommit_regions(start, num_regions);
-}
-
-void HeapRegionSeq::make_regions_available(uint start, uint num_regions) {
-  guarantee(num_regions > 0, "No point in calling this for zero regions");
-  commit_regions(start, num_regions);
-  for (uint i = start; i < start + num_regions; i++) {
-    if (_regions.get_by_index(i) == NULL) {
-      HeapRegion* new_hr = new_heap_region(i);
-      _regions.set_by_index(i, new_hr);
-      _allocated_heapregions_length = MAX2(_allocated_heapregions_length, i + 1);
-    }
-  }
-
-  _available_map.par_set_range(start, start + num_regions, BitMap::unknown_range);
-
-  for (uint i = start; i < start + num_regions; i++) {
-    assert(is_available(i), err_msg("Just made region %u available but is apparently not.", i));
-    HeapRegion* hr = at(i);
-    if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
-      G1CollectedHeap::heap()->hr_printer()->commit(hr->bottom(), hr->end());
-    }
-    HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
-    MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
-
-    hr->initialize(mr);
-    insert_into_free_list(at(i));
-  }
-}
-
-uint HeapRegionSeq::expand_by(uint num_regions) {
-  return expand_at(0, num_regions);
-}
-
-uint HeapRegionSeq::expand_at(uint start, uint num_regions) {
-  if (num_regions == 0) {
-    return 0;
-  }
-
-  uint cur = start;
-  uint idx_last_found = 0;
-  uint num_last_found = 0;
-
-  uint expanded = 0;
-
-  while (expanded < num_regions &&
-         (num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
-    uint to_expand = MIN2(num_regions - expanded, num_last_found);
-    make_regions_available(idx_last_found, to_expand);
-    expanded += to_expand;
-    cur = idx_last_found + num_last_found + 1;
-  }
-
-  verify_optional();
-  return expanded;
-}
-
-uint HeapRegionSeq::find_contiguous(size_t num, bool empty_only) {
-  uint found = 0;
-  size_t length_found = 0;
-  uint cur = 0;
-
-  while (length_found < num && cur < max_length()) {
-    HeapRegion* hr = _regions.get_by_index(cur);
-    if ((!empty_only && !is_available(cur)) || (is_available(cur) && hr != NULL && hr->is_empty())) {
-      // This region is a potential candidate for allocation into.
-      length_found++;
-    } else {
-      // This region is not a candidate. The next region is the next possible one.
-      found = cur + 1;
-      length_found = 0;
-    }
-    cur++;
-  }
-
-  if (length_found == num) {
-    for (uint i = found; i < (found + num); i++) {
-      HeapRegion* hr = _regions.get_by_index(i);
-      // sanity check
-      guarantee((!empty_only && !is_available(i)) || (is_available(i) && hr != NULL && hr->is_empty()),
-                err_msg("Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
-                        " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr)));
-    }
-    return found;
-  } else {
-    return G1_NO_HRS_INDEX;
-  }
-}
-
-HeapRegion* HeapRegionSeq::next_region_in_heap(const HeapRegion* r) const {
-  guarantee(r != NULL, "Start region must be a valid region");
-  guarantee(is_available(r->hrs_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrs_index()));
-  for (uint i = r->hrs_index() + 1; i < _allocated_heapregions_length; i++) {
-    HeapRegion* hr = _regions.get_by_index(i);
-    if (is_available(i)) {
-      return hr;
-    }
-  }
-  return NULL;
-}
-
-void HeapRegionSeq::iterate(HeapRegionClosure* blk) const {
-  uint len = max_length();
-
-  for (uint i = 0; i < len; i++) {
-    if (!is_available(i)) {
-      continue;
-    }
-    guarantee(at(i) != NULL, err_msg("Tried to access region %u that has a NULL HeapRegion*", i));
-    bool res = blk->doHeapRegion(at(i));
-    if (res) {
-      blk->incomplete();
-      return;
-    }
-  }
-}
-
-uint HeapRegionSeq::find_unavailable_from_idx(uint start_idx, uint* res_idx) const {
-  guarantee(res_idx != NULL, "checking");
-  guarantee(start_idx <= (max_length() + 1), "checking");
-
-  uint num_regions = 0;
-
-  uint cur = start_idx;
-  while (cur < max_length() && is_available(cur)) {
-    cur++;
-  }
-  if (cur == max_length()) {
-    return num_regions;
-  }
-  *res_idx = cur;
-  while (cur < max_length() && !is_available(cur)) {
-    cur++;
-  }
-  num_regions = cur - *res_idx;
-#ifdef ASSERT
-  for (uint i = *res_idx; i < (*res_idx + num_regions); i++) {
-    assert(!is_available(i), "just checking");
-  }
-  assert(cur == max_length() || num_regions == 0 || is_available(cur),
-         err_msg("The region at the current position %u must be available or at the end of the heap.", cur));
-#endif
-  return num_regions;
-}
-
-uint HeapRegionSeq::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
-  return num_regions * worker_i / num_workers;
-}
-
-void HeapRegionSeq::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
-  const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
-
-  // Every worker will actually look at all regions, skipping over regions that
-  // are currently not committed.
-  // This also (potentially) iterates over regions newly allocated during GC. This
-  // is no problem except for some extra work.
-  for (uint count = 0; count < _allocated_heapregions_length; count++) {
-    const uint index = (start_index + count) % _allocated_heapregions_length;
-    assert(0 <= index && index < _allocated_heapregions_length, "sanity");
-    // Skip over unavailable regions
-    if (!is_available(index)) {
-      continue;
-    }
-    HeapRegion* r = _regions.get_by_index(index);
-    // We'll ignore "continues humongous" regions (we'll process them
-    // when we come across their corresponding "start humongous"
-    // region) and regions already claimed.
-    if (r->claim_value() == claim_value || r->continuesHumongous()) {
-      continue;
-    }
-    // OK, try to claim it
-    if (!r->claimHeapRegion(claim_value)) {
-      continue;
-    }
-    // Success!
-    if (r->startsHumongous()) {
-      // If the region is "starts humongous" we'll iterate over its
-      // "continues humongous" first; in fact we'll do them
-      // first. The order is important. In one case, calling the
-      // closure on the "starts humongous" region might de-allocate
-      // and clear all its "continues humongous" regions and, as a
-      // result, we might end up processing them twice. So, we'll do
-      // them first (note: most closures will ignore them anyway) and
-      // then we'll do the "starts humongous" region.
-      for (uint ch_index = index + 1; ch_index < index + r->region_num(); ch_index++) {
-        HeapRegion* chr = _regions.get_by_index(ch_index);
-
-        assert(chr->continuesHumongous(), "Must be humongous region");
-        assert(chr->humongous_start_region() == r,
-               err_msg("Must work on humongous continuation of the original start region "
-                       PTR_FORMAT ", but is " PTR_FORMAT, p2i(r), p2i(chr)));
-        assert(chr->claim_value() != claim_value,
-               "Must not have been claimed yet because claiming of humongous continuation first claims the start region");
-
-        bool claim_result = chr->claimHeapRegion(claim_value);
-        // We should always be able to claim it; no one else should
-        // be trying to claim this region.
-        guarantee(claim_result, "We should always be able to claim the continuesHumongous part of the humongous object");
-
-        bool res2 = blk->doHeapRegion(chr);
-        if (res2) {
-          return;
-        }
-
-        // Right now, this holds (i.e., no closure that actually
-        // does something with "continues humongous" regions
-        // clears them). We might have to weaken it in the future,
-        // but let's leave these two asserts here for extra safety.
-        assert(chr->continuesHumongous(), "should still be the case");
-        assert(chr->humongous_start_region() == r, "sanity");
-      }
-    }
-
-    bool res = blk->doHeapRegion(r);
-    if (res) {
-      return;
-    }
-  }
-}
-
-uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
-  assert(length() > 0, "the region sequence should not be empty");
-  assert(length() <= _allocated_heapregions_length, "invariant");
-  assert(_allocated_heapregions_length > 0, "we should have at least one region committed");
-  assert(num_regions_to_remove < length(), "We should never remove all regions");
-
-  if (num_regions_to_remove == 0) {
-    return 0;
-  }
-
-  uint removed = 0;
-  uint cur = _allocated_heapregions_length - 1;
-  uint idx_last_found = 0;
-  uint num_last_found = 0;
-
-  while ((removed < num_regions_to_remove) &&
-      (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) {
-    // Only allow uncommit from the end of the heap.
-    if ((idx_last_found + num_last_found) != _allocated_heapregions_length) {
-      return 0;
-    }
-    uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found);
-
-    uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove);
-
-    cur -= num_last_found;
-    removed += to_remove;
-  }
-
-  verify_optional();
-
-  return removed;
-}
-
-uint HeapRegionSeq::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const {
-  guarantee(start_idx < _allocated_heapregions_length, "checking");
-  guarantee(res_idx != NULL, "checking");
-
-  uint num_regions_found = 0;
-
-  jlong cur = start_idx;
-  while (cur != -1 && !(is_available(cur) && at(cur)->is_empty())) {
-    cur--;
-  }
-  if (cur == -1) {
-    return num_regions_found;
-  }
-  jlong old_cur = cur;
-  // cur indexes the first empty region
-  while (cur != -1 && is_available(cur) && at(cur)->is_empty()) {
-    cur--;
-  }
-  *res_idx = cur + 1;
-  num_regions_found = old_cur - cur;
-
-#ifdef ASSERT
-  for (uint i = *res_idx; i < (*res_idx + num_regions_found); i++) {
-    assert(at(i)->is_empty(), "just checking");
-  }
-#endif
-  return num_regions_found;
-}
-
-void HeapRegionSeq::verify() {
-  guarantee(length() <= _allocated_heapregions_length,
-            err_msg("invariant: _length: %u _allocated_length: %u",
-                    length(), _allocated_heapregions_length));
-  guarantee(_allocated_heapregions_length <= max_length(),
-            err_msg("invariant: _allocated_length: %u _max_length: %u",
-                    _allocated_heapregions_length, max_length()));
-
-  bool prev_committed = true;
-  uint num_committed = 0;
-  HeapWord* prev_end = heap_bottom();
-  for (uint i = 0; i < _allocated_heapregions_length; i++) {
-    if (!is_available(i)) {
-      prev_committed = false;
-      continue;
-    }
-    num_committed++;
-    HeapRegion* hr = _regions.get_by_index(i);
-    guarantee(hr != NULL, err_msg("invariant: i: %u", i));
-    guarantee(!prev_committed || hr->bottom() == prev_end,
-              err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
-                      i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
-    guarantee(hr->hrs_index() == i,
-              err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index()));
-    // Asserts will fire if i is >= _length
-    HeapWord* addr = hr->bottom();
-    guarantee(addr_to_region(addr) == hr, "sanity");
-    // We cannot check whether the region is part of a particular set: at the time
-    // this method may be called, we have only completed allocation of the regions,
-    // but not put into a region set.
-    prev_committed = true;
-    if (hr->startsHumongous()) {
-      prev_end = hr->orig_end();
-    } else {
-      prev_end = hr->end();
-    }
-  }
-  for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
-    guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i));
-  }
-
-  guarantee(num_committed == _num_committed, err_msg("Found %u committed regions, but should be %u", num_committed, _num_committed));
-  _free_list.verify();
-}
-
-#ifndef PRODUCT
-void HeapRegionSeq::verify_optional() {
-  verify();
-}
-#endif // PRODUCT
-
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
-
-#include "gc_implementation/g1/g1BiasedArray.hpp"
-#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
-#include "gc_implementation/g1/heapRegionSet.hpp"
-
-class HeapRegion;
-class HeapRegionClosure;
-class FreeRegionList;
-
-class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
- protected:
-  virtual HeapRegion* default_value() const { return NULL; }
-};
-
-// This class keeps track of the actual heap memory, auxiliary data
-// and its metadata (i.e., HeapRegion instances) and the list of free regions.
-//
-// This allows maximum flexibility for deciding what to commit or uncommit given
-// a request from outside.
-//
-// HeapRegions are kept in the _regions array in address order. A region's
-// index in the array corresponds to its index in the heap (i.e., 0 is the
-// region at the bottom of the heap, 1 is the one after it, etc.). Two
-// regions that are consecutive in the array should also be adjacent in the
-// address space (i.e., region(i).end() == region(i+1).bottom().
-//
-// We create a HeapRegion when we commit the region's address space
-// for the first time. When we uncommit the address space of a
-// region we retain the HeapRegion to be able to re-use it in the
-// future (in case we recommit it).
-//
-// We keep track of three lengths:
-//
-// * _num_committed (returned by length()) is the number of currently
-//   committed regions. These may not be contiguous.
-// * _allocated_heapregions_length (not exposed outside this class) is the
-//   number of regions+1 for which we have HeapRegions.
-// * max_length() returns the maximum number of regions the heap can have.
-//
-
-class HeapRegionSeq: public CHeapObj<mtGC> {
-  friend class VMStructs;
-
-  G1HeapRegionTable _regions;
-
-  G1RegionToSpaceMapper* _heap_mapper;
-  G1RegionToSpaceMapper* _prev_bitmap_mapper;
-  G1RegionToSpaceMapper* _next_bitmap_mapper;
-  G1RegionToSpaceMapper* _bot_mapper;
-  G1RegionToSpaceMapper* _cardtable_mapper;
-  G1RegionToSpaceMapper* _card_counts_mapper;
-
-  FreeRegionList _free_list;
-
-  // Each bit in this bitmap indicates that the corresponding region is available
-  // for allocation.
-  BitMap _available_map;
-
-   // The number of regions committed in the heap.
-  uint _num_committed;
-
-  // Internal only. The highest heap region +1 we allocated a HeapRegion instance for.
-  uint _allocated_heapregions_length;
-
-  HeapWord* heap_bottom() const { return _regions.bottom_address_mapped(); }
-  HeapWord* heap_end() const {return _regions.end_address_mapped(); }
-
-  void make_regions_available(uint index, uint num_regions = 1);
-
-  // Pass down commit calls to the VirtualSpace.
-  void commit_regions(uint index, size_t num_regions = 1);
-  void uncommit_regions(uint index, size_t num_regions = 1);
-
-  // Notify other data structures about change in the heap layout.
-  void update_committed_space(HeapWord* old_end, HeapWord* new_end);
-  // Calculate the starting region for each worker during parallel iteration so
-  // that they do not all start from the same region.
-  uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
-
-  // Find a contiguous set of empty or uncommitted regions of length num and return
-  // the index of the first region or G1_NO_HRS_INDEX if the search was unsuccessful.
-  // If only_empty is true, only empty regions are considered.
-  // Searches from bottom to top of the heap, doing a first-fit.
-  uint find_contiguous(size_t num, bool only_empty);
-  // Finds the next sequence of unavailable regions starting from start_idx. Returns the
-  // length of the sequence found. If this result is zero, no such sequence could be found,
-  // otherwise res_idx indicates the start index of these regions.
-  uint find_unavailable_from_idx(uint start_idx, uint* res_idx) const;
-  // Finds the next sequence of empty regions starting from start_idx, going backwards in
-  // the heap. Returns the length of the sequence found. If this value is zero, no
-  // sequence could be found, otherwise res_idx contains the start index of this range.
-  uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const;
-  // Allocate a new HeapRegion for the given index.
-  HeapRegion* new_heap_region(uint hrs_index);
-#ifdef ASSERT
-public:
-  bool is_free(HeapRegion* hr) const;
-#endif
-  // Returns whether the given region is available for allocation.
-  bool is_available(uint region) const;
-
- public:
-  // Empty constructor, we'll initialize it with the initialize() method.
-  HeapRegionSeq() : _regions(), _heap_mapper(NULL), _num_committed(0),
-                    _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL),
-                    _allocated_heapregions_length(0), _available_map(),
-                    _free_list("Free list", new MasterFreeRegionListMtSafeChecker())
-  { }
-
-  void initialize(G1RegionToSpaceMapper* heap_storage,
-                  G1RegionToSpaceMapper* prev_bitmap,
-                  G1RegionToSpaceMapper* next_bitmap,
-                  G1RegionToSpaceMapper* bot,
-                  G1RegionToSpaceMapper* cardtable,
-                  G1RegionToSpaceMapper* card_counts);
-
-  // Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
-  // new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit
-  // the heap from the lowest address, this region (and its associated data
-  // structures) are available and we do not need to check further.
-  HeapRegion* get_dummy_region() { return new_heap_region(0); }
-
-  // Return the HeapRegion at the given index. Assume that the index
-  // is valid.
-  inline HeapRegion* at(uint index) const;
-
-  // If addr is within the committed space return its corresponding
-  // HeapRegion, otherwise return NULL.
-  inline HeapRegion* addr_to_region(HeapWord* addr) const;
-
-  // Insert the given region into the free region list.
-  inline void insert_into_free_list(HeapRegion* hr);
-
-  // Insert the given region list into the global free region list.
-  void insert_list_into_free_list(FreeRegionList* list) {
-    _free_list.add_ordered(list);
-  }
-
-  HeapRegion* allocate_free_region(bool is_old) {
-    HeapRegion* hr = _free_list.remove_region(is_old);
-
-    if (hr != NULL) {
-      assert(hr->next() == NULL, "Single region should not have next");
-      assert(is_available(hr->hrs_index()), "Must be committed");
-    }
-    return hr;
-  }
-
-  inline void allocate_free_regions_starting_at(uint first, uint num_regions);
-
-  // Remove all regions from the free list.
-  void remove_all_free_regions() {
-    _free_list.remove_all();
-  }
-
-  // Return the number of committed free regions in the heap.
-  uint num_free_regions() const {
-    return _free_list.length();
-  }
-
-  size_t total_capacity_bytes() const {
-    return num_free_regions() * HeapRegion::GrainBytes;
-  }
-
-  // Return the number of available (uncommitted) regions.
-  uint available() const { return max_length() - length(); }
-
-  // Return the number of regions that have been committed in the heap.
-  uint length() const { return _num_committed; }
-
-  // Return the maximum number of regions in the heap.
-  uint max_length() const { return (uint)_regions.length(); }
-
-  MemRegion reserved() const { return MemRegion(heap_bottom(), heap_end()); }
-
-  // Expand the sequence to reflect that the heap has grown. Either create new
-  // HeapRegions, or re-use existing ones. Returns the number of regions the
-  // sequence was expanded by. If a HeapRegion allocation fails, the resulting
-  // number of regions might be smaller than what's desired.
-  uint expand_by(uint num_regions);
-
-  // Makes sure that the regions from start to start+num_regions-1 are available
-  // for allocation. Returns the number of regions that were committed to achieve
-  // this.
-  uint expand_at(uint start, uint num_regions);
-
-  // Find a contiguous set of empty regions of length num. Returns the start index of
-  // that set, or G1_NO_HRS_INDEX.
-  uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
-  // Find a contiguous set of empty or unavailable regions of length num. Returns the
-  // start index of that set, or G1_NO_HRS_INDEX.
-  uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
-
-  HeapRegion* next_region_in_heap(const HeapRegion* r) const;
-
-  // Apply blk->doHeapRegion() on all committed regions in address order,
-  // terminating the iteration early if doHeapRegion() returns true.
-  void iterate(HeapRegionClosure* blk) const;
-
-  void par_iterate(HeapRegionClosure* blk, uint worker_id, uint no_of_par_workers, jint claim_value) const;
-
-  // Uncommit up to num_regions_to_remove regions that are completely free.
-  // Return the actual number of uncommitted regions.
-  uint shrink_by(uint num_regions_to_remove);
-
-  void verify();
-
-  // Do some sanity checking.
-  void verify_optional() PRODUCT_RETURN;
-};
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP
-
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2001, 2014, 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.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
-
-#include "gc_implementation/g1/heapRegion.hpp"
-#include "gc_implementation/g1/heapRegionSeq.hpp"
-#include "gc_implementation/g1/heapRegionSet.inline.hpp"
-
-inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
-  assert(addr < heap_end(),
-        err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end())));
-  assert(addr >= heap_bottom(),
-        err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT, p2i(addr), p2i(heap_bottom())));
-
-  HeapRegion* hr = _regions.get_by_address(addr);
-  return hr;
-}
-
-inline HeapRegion* HeapRegionSeq::at(uint index) const {
-  assert(is_available(index), "pre-condition");
-  HeapRegion* hr = _regions.get_by_index(index);
-  assert(hr != NULL, "sanity");
-  assert(hr->hrs_index() == index, "sanity");
-  return hr;
-}
-
-inline void HeapRegionSeq::insert_into_free_list(HeapRegion* hr) {
-  _free_list.add_ordered(hr);
-}
-
-inline void HeapRegionSeq::allocate_free_regions_starting_at(uint first, uint num_regions) {
-  _free_list.remove_starting_at(at(first), num_regions);
-}
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -39,11 +39,11 @@
 
 #ifndef PRODUCT
 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
-  assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index()));
-  assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions
-  assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name()));
-  assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name()));
-  assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index()));
+  assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index()));
+  assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions
+  assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name()));
+  assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrm_index(), name()));
+  assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index()));
 }
 #endif
 
@@ -158,7 +158,7 @@
     HeapRegion* curr_from = from_list->_head;
 
     while (curr_from != NULL) {
-      while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) {
+      while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) {
         curr_to = curr_to->next();
       }
 
@@ -183,7 +183,7 @@
       }
     }
 
-    if (_tail->hrs_index() < from_list->_tail->hrs_index()) {
+    if (_tail->hrm_index() < from_list->_tail->hrm_index()) {
       _tail = from_list->_tail;
     }
   }
@@ -309,8 +309,8 @@
     if (curr->next() != NULL) {
       guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
     }
-    guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted");
-    last_index = curr->hrs_index();
+    guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
+    last_index = curr->hrm_index();
 
     capacity += curr->capacity();
 
@@ -319,7 +319,7 @@
     curr = curr->next();
   }
 
-  guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrs_index(), prev0->hrs_index()));
+  guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index()));
   guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
   guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count));
   guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -238,14 +238,14 @@
 
   // Add hr to the list. The region should not be a member of another set.
   // Assumes that the list is ordered and will preserve that order. The order
-  // is determined by hrs_index.
+  // is determined by hrm_index.
   inline void add_ordered(HeapRegion* hr);
 
   // Removes from head or tail based on the given argument.
   HeapRegion* remove_region(bool from_head);
 
   // Merge two ordered lists. The result is also ordered. The order is
-  // determined by hrs_index.
+  // determined by hrm_index.
   void add_ordered(FreeRegionList* from_list);
 
   // It empties the list by removing all regions from it.
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -60,14 +60,14 @@
   if (_head != NULL) {
     HeapRegion* curr;
 
-    if (_last != NULL && _last->hrs_index() < hr->hrs_index()) {
+    if (_last != NULL && _last->hrm_index() < hr->hrm_index()) {
       curr = _last;
     } else {
       curr = _head;
     }
 
     // Find first entry with a Region Index larger than entry to insert.
-    while (curr != NULL && curr->hrs_index() < hr->hrs_index()) {
+    while (curr != NULL && curr->hrm_index() < hr->hrm_index()) {
       curr = curr->next();
     }
 
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -453,7 +453,7 @@
 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
 #if SPARSE_PRT_VERBOSE
   gclog_or_tty->print_cr("  Adding card %d from region %d to region %u sparse.",
-                         card_index, region_id, _hr->hrs_index());
+                         card_index, region_id, _hr->hrm_index());
 #endif
   if (_next->occupied_entries() * 2 > _next->capacity()) {
     expand();
@@ -505,7 +505,7 @@
 
 #if SPARSE_PRT_VERBOSE
   gclog_or_tty->print_cr("  Expanded sparse table for %u to %d.",
-                         _hr->hrs_index(), _next->capacity());
+                         _hr->hrm_index(), _next->capacity());
 #endif
   for (size_t i = 0; i < last->capacity(); i++) {
     SparsePRTEntry* e = last->entry((int)i);
--- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP
 
 #include "gc_implementation/g1/heapRegion.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 
 #define VM_STRUCTS_G1(nonstatic_field, static_field)                          \
@@ -42,10 +42,10 @@
   nonstatic_field(G1HeapRegionTable, _bias,             size_t)               \
   nonstatic_field(G1HeapRegionTable, _shift_by,         uint)                 \
                                                                               \
-  nonstatic_field(HeapRegionSeq,   _regions,            G1HeapRegionTable)    \
-  nonstatic_field(HeapRegionSeq,   _num_committed,      uint)                 \
+  nonstatic_field(HeapRegionManager, _regions,          G1HeapRegionTable)    \
+  nonstatic_field(HeapRegionManager, _num_committed,    uint)                 \
                                                                               \
-  nonstatic_field(G1CollectedHeap, _hrs,                HeapRegionSeq)        \
+  nonstatic_field(G1CollectedHeap, _hrm,                HeapRegionManager)    \
   nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t)               \
   nonstatic_field(G1CollectedHeap, _g1mm,               G1MonitoringSupport*) \
   nonstatic_field(G1CollectedHeap, _old_set,            HeapRegionSetBase)    \
@@ -72,7 +72,7 @@
                                                                               \
   declare_type(G1OffsetTableContigSpace, CompactibleSpace)                    \
   declare_type(HeapRegion, G1OffsetTableContigSpace)                          \
-  declare_toplevel_type(HeapRegionSeq)                                        \
+  declare_toplevel_type(HeapRegionManager)                                        \
   declare_toplevel_type(HeapRegionSetBase)                                    \
   declare_toplevel_type(HeapRegionSetCount)                                   \
   declare_toplevel_type(G1MonitoringSupport)                                  \
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -30,6 +30,8 @@
 
 PSGenerationCounters::PSGenerationCounters(const char* name,
                                        int ordinal, int spaces,
+                                       size_t min_capacity,
+                                       size_t max_capacity,
                                        PSVirtualSpace* v):
     _ps_virtual_space(v) {
 
@@ -52,11 +54,11 @@
 
     cname = PerfDataManager::counter_name(_name_space, "minCapacity");
     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-      _ps_virtual_space->committed_size(), CHECK);
+      min_capacity, CHECK);
 
     cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
-      _ps_virtual_space->reserved_size(), CHECK);
+      max_capacity, CHECK);
 
     cname = PerfDataManager::counter_name(_name_space, "capacity");
     _current_size = PerfDataManager::create_variable(SUN_GC, cname,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -41,7 +41,7 @@
 
  public:
   PSGenerationCounters(const char* name, int ordinal, int spaces,
-                     PSVirtualSpace* v);
+                       size_t min_capacity, size_t max_capacity, PSVirtualSpace* v);
 
   void update_all() {
     assert(_virtual_space == NULL, "Only one should be in use");
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -149,8 +149,8 @@
 
 void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) {
   // Generation Counters, generation 'level', 1 subspace
-  _gen_counters = new PSGenerationCounters(perf_data_name, level, 1,
-                                           virtual_space());
+  _gen_counters = new PSGenerationCounters(perf_data_name, level, 1, _min_gen_size,
+                                           _max_gen_size, virtual_space());
   _space_counters = new SpaceCounters(perf_data_name, 0,
                                       virtual_space()->reserved_size(),
                                       _object_space, _gen_counters);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -101,7 +101,8 @@
   }
 
   // Generation Counters - generation 0, 3 subspaces
-  _gen_counters = new PSGenerationCounters("new", 0, 3, _virtual_space);
+  _gen_counters = new PSGenerationCounters("new", 0, 3, _min_gen_size,
+                                           _max_gen_size, _virtual_space);
 
   // Compute maximum space sizes for performance counters
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
--- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -62,11 +62,12 @@
 
 GenerationCounters::GenerationCounters(const char* name,
                                        int ordinal, int spaces,
+                                       size_t min_capacity, size_t max_capacity,
                                        VirtualSpace* v)
   : _virtual_space(v) {
   assert(v != NULL, "don't call this constructor if v == NULL");
   initialize(name, ordinal, spaces,
-             v->committed_size(), v->reserved_size(), v->committed_size());
+             min_capacity, max_capacity, v->committed_size());
 }
 
 GenerationCounters::GenerationCounters(const char* name,
--- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -66,7 +66,7 @@
 
  public:
   GenerationCounters(const char* name, int ordinal, int spaces,
-                     VirtualSpace* v);
+                     size_t min_capacity, size_t max_capacity, VirtualSpace* v);
 
   ~GenerationCounters() {
     if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -214,9 +214,11 @@
   _max_eden_size = size - (2*_max_survivor_size);
 
   // allocate the performance counters
+  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
 
   // Generation counters -- generation 0, 3 subspaces
-  _gen_counters = new GenerationCounters("new", 0, 3, &_virtual_space);
+  _gen_counters = new GenerationCounters("new", 0, 3,
+      gcp->min_young_size(), gcp->max_young_size(), &_virtual_space);
   _gc_counters = new CollectorCounters(policy, 0);
 
   _eden_counters = new CSpaceCounters("eden", 0, _max_eden_size, _eden_space,
--- a/hotspot/src/share/vm/memory/filemap.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -445,7 +445,7 @@
       // close and remove the file. See bug 6372906.
       close();
       remove(_full_path);
-      fail_stop("Unable to write to shared archive file.", NULL);
+      fail_stop("Unable to write to shared archive file.");
     }
   }
   _file_offset += nbytes;
@@ -463,7 +463,7 @@
       // that the written file is the correct length.
       _file_offset -= 1;
       if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
-        fail_stop("Unable to seek.", NULL);
+        fail_stop("Unable to seek.");
       }
       char zero = 0;
       write_bytes(&zero, 1);
@@ -534,7 +534,7 @@
   // other reserved memory (like the code cache).
   ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
   if (!rs.is_reserved()) {
-    fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
+    fail_continue("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr);
     return rs;
   }
   // the reserved virtual memory is for mapping class data sharing archive
@@ -558,7 +558,7 @@
                               requested_addr, size, si->_read_only,
                               si->_allow_exec);
   if (base == NULL || base != si->_base) {
-    fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i]));
+    fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
     return NULL;
   }
 #ifdef _WINDOWS
@@ -584,7 +584,7 @@
 
 void FileMapInfo::assert_mark(bool check) {
   if (!check) {
-    fail_stop("Mark mismatch while restoring from shared file.", NULL);
+    fail_stop("Mark mismatch while restoring from shared file.");
   }
 }
 
@@ -709,7 +709,7 @@
 void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
   FileMapInfo *map_info = FileMapInfo::current_info();
   if (map_info) {
-    map_info->fail_continue(msg);
+    map_info->fail_continue("%s", msg);
     for (int i = 0; i < MetaspaceShared::n_regions; i++) {
       if (map_info->_header->_space[i]._base != NULL) {
         map_info->unmap_region(i);
@@ -717,6 +717,6 @@
       }
     }
   } else if (DumpSharedSpaces) {
-    fail_stop(msg, NULL);
+    fail_stop("%s", msg);
   }
 }
--- a/hotspot/src/share/vm/memory/filemap.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -190,8 +190,8 @@
   bool  remap_shared_readonly_as_readwrite();
 
   // Errors.
-  static void fail_stop(const char *msg, ...);
-  static void fail_continue(const char *msg, ...);
+  static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
+  static void fail_continue(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
 
   // Return true if given address is in the mapped shared space.
   bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -3126,6 +3126,8 @@
 
   if (DumpSharedSpaces) {
 #if INCLUDE_CDS
+    MetaspaceShared::estimate_regions_size();
+
     SharedReadOnlySize  = align_size_up(SharedReadOnlySize,  max_alignment);
     SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment);
     SharedMiscDataSize  = align_size_up(SharedMiscDataSize,  max_alignment);
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -816,6 +816,7 @@
         //tty->print_cr("Preload failed: %s", class_name);
       }
     }
+    fclose(file);
   } else {
     char errmsg[JVM_MAXPATHLEN];
     os::lasterror(errmsg, JVM_MAXPATHLEN);
@@ -1086,3 +1087,49 @@
   }
   return true;
 }
+
+int MetaspaceShared::count_class(const char* classlist_file) {
+  if (classlist_file == NULL) {
+    return 0;
+  }
+  char class_name[256];
+  int class_count = 0;
+  FILE* file = fopen(classlist_file, "r");
+  if (file != NULL) {
+    while ((fgets(class_name, sizeof class_name, file)) != NULL) {
+      if (*class_name == '#') { // comment
+        continue;
+      }
+      class_count++;
+    }
+    fclose(file);
+  } else {
+    char errmsg[JVM_MAXPATHLEN];
+    os::lasterror(errmsg, JVM_MAXPATHLEN);
+    tty->print_cr("Loading classlist failed: %s", errmsg);
+    exit(1);
+  }
+
+  return class_count;
+}
+
+// the sizes are good for typical large applications that have a lot of shared
+// classes
+void MetaspaceShared::estimate_regions_size() {
+  int class_count = count_class(SharedClassListFile);
+  class_count += count_class(ExtraSharedClassListFile);
+
+  if (class_count > LargeThresholdClassCount) {
+    if (class_count < HugeThresholdClassCount) {
+      SET_ESTIMATED_SIZE(Large, ReadOnly);
+      SET_ESTIMATED_SIZE(Large, ReadWrite);
+      SET_ESTIMATED_SIZE(Large, MiscData);
+      SET_ESTIMATED_SIZE(Large, MiscCode);
+    } else {
+      SET_ESTIMATED_SIZE(Huge,  ReadOnly);
+      SET_ESTIMATED_SIZE(Huge,  ReadWrite);
+      SET_ESTIMATED_SIZE(Huge,  MiscData);
+      SET_ESTIMATED_SIZE(Huge,  MiscCode);
+    }
+  }
+}
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -30,6 +30,19 @@
 #include "utilities/exceptions.hpp"
 #include "utilities/macros.hpp"
 
+#define LargeSharedArchiveSize    (300*M)
+#define HugeSharedArchiveSize     (800*M)
+#define ReadOnlyRegionPercentage  0.4
+#define ReadWriteRegionPercentage 0.55
+#define MiscDataRegionPercentage  0.03
+#define MiscCodeRegionPercentage  0.02
+#define LargeThresholdClassCount  5000
+#define HugeThresholdClassCount   40000
+
+#define SET_ESTIMATED_SIZE(type, region)                              \
+  Shared ##region## Size  = FLAG_IS_DEFAULT(Shared ##region## Size) ? \
+    (type ## SharedArchiveSize *  region ## RegionPercentage) : Shared ## region ## Size
+
 class FileMapInfo;
 
 // Class Data Sharing Support
@@ -112,5 +125,8 @@
   static void link_one_shared_class(Klass* obj, TRAPS);
   static void check_one_shared_class(Klass* obj);
   static void link_and_cleanup_shared_classes(TRAPS);
+
+  static int count_class(const char* classlist_file);
+  static void estimate_regions_size() NOT_CDS_RETURN;
 };
 #endif // SHARE_VM_MEMORY_METASPACE_SHARED_HPP
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -53,9 +53,11 @@
   // initialize performance counters
 
   const char* gen_name = "old";
+  GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
 
   // Generation Counters -- generation 1, 1 subspace
-  _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space);
+  _gen_counters = new GenerationCounters(gen_name, 1, 1,
+      gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
 
   _gc_counters = new CollectorCounters("MSC", 1);
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -68,7 +68,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -42,7 +42,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -38,7 +38,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -51,7 +51,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
-#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionManager.inline.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
 #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -1708,8 +1708,8 @@
 // Make a TypeTuple from the range of a method signature
 const TypeTuple *TypeTuple::make_range(ciSignature* sig) {
   ciType* return_type = sig->return_type();
-  uint total_fields = TypeFunc::Parms + return_type->size();
-  const Type **field_array = fields(total_fields);
+  uint arg_cnt = return_type->size();
+  const Type **field_array = fields(arg_cnt);
   switch (return_type->basic_type()) {
   case T_LONG:
     field_array[TypeFunc::Parms]   = TypeLong::LONG;
@@ -1734,26 +1734,26 @@
   default:
     ShouldNotReachHere();
   }
-  return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons();
+  return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
 }
 
 // Make a TypeTuple from the domain of a method signature
 const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig) {
-  uint total_fields = TypeFunc::Parms + sig->size();
+  uint arg_cnt = sig->size();
 
   uint pos = TypeFunc::Parms;
   const Type **field_array;
   if (recv != NULL) {
-    total_fields++;
-    field_array = fields(total_fields);
+    arg_cnt++;
+    field_array = fields(arg_cnt);
     // Use get_const_type here because it respects UseUniqueSubclasses:
     field_array[pos++] = get_const_type(recv)->join_speculative(TypePtr::NOTNULL);
   } else {
-    field_array = fields(total_fields);
+    field_array = fields(arg_cnt);
   }
 
   int i = 0;
-  while (pos < total_fields) {
+  while (pos < TypeFunc::Parms + arg_cnt) {
     ciType* type = sig->type_at(i);
 
     switch (type->basic_type()) {
@@ -1780,7 +1780,8 @@
     }
     i++;
   }
-  return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons();
+
+  return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
 }
 
 const TypeTuple *TypeTuple::make( uint cnt, const Type **fields ) {
@@ -1789,6 +1790,7 @@
 
 //------------------------------fields-----------------------------------------
 // Subroutine call type with space allocated for argument types
+// Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly
 const Type **TypeTuple::fields( uint arg_cnt ) {
   const Type **flds = (const Type **)(Compile::current()->type_arena()->Amalloc_4((TypeFunc::Parms+arg_cnt)*sizeof(Type*) ));
   flds[TypeFunc::Control  ] = Type::CONTROL;
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -635,6 +635,7 @@
   static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig);
 
   // Subroutine call type with space allocated for argument types
+  // Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly
   static const Type **fields( uint arg_cnt );
 
   virtual const Type *xmeet( const Type *t ) const;
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -430,6 +430,8 @@
   }
 }
 
+jint volatile vm_getting_terminated = 0;
+
 // Note: before_exit() can be executed only once, if more than one threads
 //       are trying to shutdown the VM at the same time, only one thread
 //       can run before_exit() and all other threads must wait.
@@ -460,6 +462,8 @@
     }
   }
 
+  OrderAccess::release_store(&vm_getting_terminated, 1);
+
   // The only difference between this and Win32's _onexit procs is that
   // this version is invoked before any threads get killed.
   ExitProc* current = exit_procs;
--- a/hotspot/src/share/vm/services/mallocTracker.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocTracker.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -171,8 +171,9 @@
   // Total malloc'd memory used by arenas
   size_t total_arena() const;
 
-  inline size_t thread_count() {
-    return by_type(mtThreadStack)->malloc_count();
+  inline size_t thread_count() const {
+    MallocMemorySnapshot* s = const_cast<MallocMemorySnapshot*>(this);
+    return s->by_type(mtThreadStack)->malloc_count();
   }
 
   void reset();
--- a/hotspot/src/share/vm/services/memBaseline.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/services/memBaseline.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -70,15 +70,13 @@
  */
 class MallocAllocationSiteWalker : public MallocSiteWalker {
  private:
-  SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA>
-                 _malloc_sites;
+  SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;
   size_t         _count;
 
   // Entries in MallocSiteTable with size = 0 and count = 0,
   // when the malloc site is not longer there.
  public:
-  MallocAllocationSiteWalker(Arena* arena) : _count(0), _malloc_sites(arena) {
-  }
+  MallocAllocationSiteWalker() : _count(0) { }
 
   inline size_t count() const { return _count; }
 
@@ -109,13 +107,12 @@
 // Walk all virtual memory regions for baselining
 class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
  private:
-  SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base, ResourceObj::ARENA>
+  SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>
                 _virtual_memory_regions;
   size_t        _count;
 
  public:
-  VirtualMemoryAllocationWalker(Arena* a) : _count(0), _virtual_memory_regions(a) {
-  }
+  VirtualMemoryAllocationWalker() : _count(0) { }
 
   bool do_allocation_site(const ReservedMemoryRegion* rgn)  {
     if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) {
@@ -136,39 +133,30 @@
 
 
 bool MemBaseline::baseline_summary() {
-  assert(_malloc_memory_snapshot == NULL, "Malloc baseline not yet reset");
-  assert(_virtual_memory_snapshot == NULL, "Virtual baseline not yet reset");
-
-  _malloc_memory_snapshot =  new (arena()) MallocMemorySnapshot();
-  _virtual_memory_snapshot = new (arena()) VirtualMemorySnapshot();
-  if (_malloc_memory_snapshot == NULL || _virtual_memory_snapshot == NULL) {
-    return false;
-  }
-  MallocMemorySummary::snapshot(_malloc_memory_snapshot);
-  VirtualMemorySummary::snapshot(_virtual_memory_snapshot);
+  MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
+  VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
   return true;
 }
 
 bool MemBaseline::baseline_allocation_sites() {
-  assert(arena() != NULL, "Just check");
   // Malloc allocation sites
-  MallocAllocationSiteWalker malloc_walker(arena());
+  MallocAllocationSiteWalker malloc_walker;
   if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {
     return false;
   }
 
-  _malloc_sites.set_head(malloc_walker.malloc_sites()->head());
+  _malloc_sites.move(malloc_walker.malloc_sites());
   // The malloc sites are collected in size order
   _malloc_sites_order = by_size;
 
   // Virtual memory allocation sites
-  VirtualMemoryAllocationWalker virtual_memory_walker(arena());
+  VirtualMemoryAllocationWalker virtual_memory_walker;
   if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {
     return false;
   }
 
   // Virtual memory allocations are collected in call stack order
-  _virtual_memory_allocations.set_head(virtual_memory_walker.virtual_memory_allocations()->head());
+  _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
 
   if (!aggregate_virtual_memory_allocation_sites()) {
     return false;
@@ -180,11 +168,6 @@
 }
 
 bool MemBaseline::baseline(bool summaryOnly) {
-  if (arena() == NULL) {
-    _arena = new (std::nothrow, mtNMT) Arena(mtNMT);
-    if (arena() == NULL) return false;
-  }
-
   reset();
 
   _class_count = InstanceKlass::number_of_instance_classes();
@@ -211,8 +194,7 @@
 }
 
 bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
-  SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site, ResourceObj::ARENA>
-    allocation_sites(arena());
+  SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
 
   VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
   const ReservedMemoryRegion* rgn;
@@ -230,12 +212,12 @@
     site->commit_memory(rgn->committed_size());
   }
 
-  _virtual_memory_sites.set_head(allocation_sites.head());
+  _virtual_memory_sites.move(&allocation_sites);
   return true;
 }
 
 MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
-  assert(!_malloc_sites.is_empty(), "Detail baseline?");
+  assert(!_malloc_sites.is_empty(), "Not detail baseline");
   switch(order) {
     case by_size:
       malloc_sites_to_size_order();
@@ -251,7 +233,7 @@
 }
 
 VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {
-  assert(!_virtual_memory_sites.is_empty(), "Detail baseline?");
+  assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");
   switch(order) {
     case by_size:
       virtual_memory_sites_to_size_order();
@@ -270,8 +252,7 @@
 // Sorting allocations sites in different orders
 void MemBaseline::malloc_sites_to_size_order() {
   if (_malloc_sites_order != by_size) {
-    SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA>
-      tmp(arena());
+    SortedLinkedList<MallocSite, compare_malloc_size> tmp;
 
     // Add malloc sites to sorted linked list to sort into size order
     tmp.move(&_malloc_sites);
@@ -283,8 +264,7 @@
 
 void MemBaseline::malloc_sites_to_allocation_site_order() {
   if (_malloc_sites_order != by_site) {
-    SortedLinkedList<MallocSite, compare_malloc_site, ResourceObj::ARENA>
-      tmp(arena());
+    SortedLinkedList<MallocSite, compare_malloc_site> tmp;
     // Add malloc sites to sorted linked list to sort into site (address) order
     tmp.move(&_malloc_sites);
     _malloc_sites.set_head(tmp.head());
@@ -295,8 +275,7 @@
 
 void MemBaseline::virtual_memory_sites_to_size_order() {
   if (_virtual_memory_sites_order != by_size) {
-    SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size, ResourceObj::ARENA>
-      tmp(arena());
+    SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
 
     tmp.move(&_virtual_memory_sites);
 
@@ -308,10 +287,9 @@
 
 void MemBaseline::virtual_memory_sites_to_reservation_site_order() {
   if (_virtual_memory_sites_order != by_size) {
-    SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site, ResourceObj::ARENA>
-      tmp(arena());
+    SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;
 
-    tmp.add(&_virtual_memory_sites);
+    tmp.move(&_virtual_memory_sites);
 
     _virtual_memory_sites.set_head(tmp.head());
     tmp.set_head(NULL);
--- a/hotspot/src/share/vm/services/memBaseline.hpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/src/share/vm/services/memBaseline.hpp	Wed Jul 05 20:00:07 2017 +0200
@@ -61,28 +61,22 @@
   };
 
  private:
-  // All baseline data is stored in this arena
-  Arena*                  _arena;
-
   // Summary information
-  MallocMemorySnapshot*   _malloc_memory_snapshot;
-  VirtualMemorySnapshot*  _virtual_memory_snapshot;
+  MallocMemorySnapshot   _malloc_memory_snapshot;
+  VirtualMemorySnapshot  _virtual_memory_snapshot;
 
   size_t               _class_count;
 
   // Allocation sites information
   // Malloc allocation sites
-  LinkedListImpl<MallocSite, ResourceObj::ARENA>
-                       _malloc_sites;
+  LinkedListImpl<MallocSite>                  _malloc_sites;
 
   // All virtual memory allocations
-  LinkedListImpl<ReservedMemoryRegion, ResourceObj::ARENA>
-                       _virtual_memory_allocations;
+  LinkedListImpl<ReservedMemoryRegion>        _virtual_memory_allocations;
 
   // Virtual memory allocations by allocation sites, always in by_address
   // order
-  LinkedListImpl<VirtualMemoryAllocationSite, ResourceObj::ARENA>
-                       _virtual_memory_sites;
+  LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites;
 
   SortingOrder         _malloc_sites_order;
   SortingOrder         _virtual_memory_sites_order;
@@ -93,30 +87,23 @@
   // create a memory baseline
   MemBaseline():
     _baseline_type(Not_baselined),
-    _class_count(0),
-    _arena(NULL),
-    _malloc_memory_snapshot(NULL),
-    _virtual_memory_snapshot(NULL),
-    _malloc_sites(NULL) {
+    _class_count(0) {
   }
 
   ~MemBaseline() {
     reset();
-    if (_arena != NULL) {
-      delete _arena;
-    }
   }
 
   bool baseline(bool summaryOnly = true);
 
   BaselineType baseline_type() const { return _baseline_type; }
 
-  MallocMemorySnapshot* malloc_memory_snapshot() const {
-    return _malloc_memory_snapshot;
+  MallocMemorySnapshot* malloc_memory_snapshot() {
+    return &_malloc_memory_snapshot;
   }
 
-  VirtualMemorySnapshot* virtual_memory_snapshot() const {
-    return _virtual_memory_snapshot;
+  VirtualMemorySnapshot* virtual_memory_snapshot() {
+    return &_virtual_memory_snapshot;
   }
 
   MallocSiteIterator malloc_sites(SortingOrder order);
@@ -133,10 +120,8 @@
   // memory
   size_t total_reserved_memory() const {
     assert(baseline_type() != Not_baselined, "Not yet baselined");
-    assert(_virtual_memory_snapshot != NULL, "No virtual memory snapshot");
-    assert(_malloc_memory_snapshot != NULL,  "No malloc memory snapshot");
-    size_t amount = _malloc_memory_snapshot->total() +
-           _virtual_memory_snapshot->total_reserved();
+    size_t amount = _malloc_memory_snapshot.total() +
+           _virtual_memory_snapshot.total_reserved();
     return amount;
   }
 
@@ -144,32 +129,30 @@
   // virtual memory
   size_t total_committed_memory() const {
     assert(baseline_type() != Not_baselined, "Not yet baselined");
-    assert(_virtual_memory_snapshot != NULL,
-      "Not a snapshot");
-    size_t amount = _malloc_memory_snapshot->total() +
-           _virtual_memory_snapshot->total_committed();
+    size_t amount = _malloc_memory_snapshot.total() +
+           _virtual_memory_snapshot.total_committed();
     return amount;
   }
 
   size_t total_arena_memory() const {
     assert(baseline_type() != Not_baselined, "Not yet baselined");
-    assert(_malloc_memory_snapshot != NULL, "Not yet baselined");
-    return _malloc_memory_snapshot->total_arena();
+    return _malloc_memory_snapshot.total_arena();
   }
 
   size_t malloc_tracking_overhead() const {
     assert(baseline_type() != Not_baselined, "Not yet baselined");
-    return _malloc_memory_snapshot->malloc_overhead()->size();
+    MemBaseline* bl = const_cast<MemBaseline*>(this);
+    return bl->_malloc_memory_snapshot.malloc_overhead()->size();
   }
 
-  const MallocMemory* malloc_memory(MEMFLAGS flag) const {
-    assert(_malloc_memory_snapshot != NULL, "Not a snapshot");
-    return _malloc_memory_snapshot->by_type(flag);
+  MallocMemory* malloc_memory(MEMFLAGS flag) {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    return _malloc_memory_snapshot.by_type(flag);
   }
 
-  const VirtualMemory* virtual_memory(MEMFLAGS flag) const {
-    assert(_virtual_memory_snapshot != NULL, "Not a snapshot");
-    return _virtual_memory_snapshot->by_type(flag);
+  VirtualMemory* virtual_memory(MEMFLAGS flag) {
+    assert(baseline_type() != Not_baselined, "Not yet baselined");
+    return _virtual_memory_snapshot.by_type(flag);
   }
 
 
@@ -180,24 +163,19 @@
 
   size_t thread_count() const {
     assert(baseline_type() != Not_baselined, "Not yet baselined");
-    assert(_malloc_memory_snapshot != NULL, "Baselined?");
-    return _malloc_memory_snapshot->thread_count();
+    return _malloc_memory_snapshot.thread_count();
   }
 
   // reset the baseline for reuse
   void reset() {
     _baseline_type = Not_baselined;
-    _malloc_memory_snapshot = NULL;
-    _virtual_memory_snapshot = NULL;
+    _malloc_memory_snapshot.reset();
+    _virtual_memory_snapshot.reset();
     _class_count  = 0;
 
-    _malloc_sites = NULL;
-    _virtual_memory_sites = NULL;
-    _virtual_memory_allocations = NULL;
-
-    if (_arena != NULL) {
-      _arena->destruct_contents();
-    }
+    _malloc_sites.clear();
+    _virtual_memory_sites.clear();
+    _virtual_memory_allocations.clear();
   }
 
  private:
@@ -210,8 +188,6 @@
   // Aggregate virtual memory allocation by allocation sites
   bool aggregate_virtual_memory_allocation_sites();
 
-  Arena* arena() { return _arena; }
-
   // Sorting allocation sites in different orders
   // Sort allocation sites in size order
   void malloc_sites_to_size_order();
--- a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java	Wed Jul 05 20:00:07 2017 +0200
@@ -35,7 +35,9 @@
  * @summary "Tests unloading of anonymous classes."
  * @library /testlibrary /testlibrary/whitebox
  * @compile TestAnonymousClassUnloading.java
- * @run main ClassFileInstaller TestAnonymousClassUnloading sun.hotspot.WhiteBox
+ * @run main ClassFileInstaller TestAnonymousClassUnloading
+ *                              sun.hotspot.WhiteBox
+ *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestAnonymousClassUnloading
  */
 public class TestAnonymousClassUnloading {
--- a/hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java	Wed Jul 05 20:00:07 2017 +0200
@@ -36,7 +36,7 @@
  * @build WorkerClass
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:+UseParallelGC -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading
  */
 public class TestMethodUnloading {
     private static final String workerClassName = "WorkerClass";
--- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java	Wed Jul 05 20:00:07 2017 +0200
@@ -54,16 +54,19 @@
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
                 TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
                 CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:+UseRTMLocking");
 
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
                 TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
                 CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:-UseRTMLocking", prepareOptionValue("true"));
 
         // verify that option could be turned on
         CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
                 CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:+UseRTMLocking", prepareOptionValue("true"));
     }
 
--- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java	Wed Jul 05 20:00:07 2017 +0200
@@ -63,13 +63,16 @@
         // verify default value
         CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
                 TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:+UseRTMLocking");
         // verify that option is off when UseRTMLocking is off
-        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
-                "false", "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "false",
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
         // verify that option could be turned on
-        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
-                "true", "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
+        CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "true",
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
     }
 
     public static void main(String args[]) throws Throwable {
--- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java	Wed Jul 05 20:00:07 2017 +0200
@@ -59,24 +59,31 @@
                 new String[]{
                         RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
                         unrecongnizedOption
-                }, ExitCode.OK, "-XX:+UseRTMLocking"
+                }, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking"
         );
 
         CommandLineOptionTest.verifySameJVMStartup(null,
                 new String[]{
                         RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
                         unrecongnizedOption
-                }, ExitCode.OK, "-XX:-UseRTMLocking"
+                }, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:-UseRTMLocking"
         );
         // verify that UseRTMLocking is of by default
         CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
-                TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE);
+                TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
         // verify that we can change UseRTMLocking value
         CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
                 TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:-UseRTMLocking");
         CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
-                "true", "-XX:+UseRTMLocking");
+                "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking");
     }
 
     public static void main(String args[]) throws Throwable {
--- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java	Wed Jul 05 20:00:07 2017 +0200
@@ -54,18 +54,22 @@
         // verify that we will not get a warning
         CommandLineOptionTest.verifySameJVMStartup(null,
                 new String[] { warningMessage }, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking");
         // verify that we will get a warning
         CommandLineOptionTest.verifySameJVMStartup(
                 new String[] { warningMessage }, null, ExitCode.OK,
+                CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
                 "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
         // verify that UseBiasedLocking is false when we use rtm locking
         CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
-                "false", "-XX:+UseRTMLocking");
+                "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking");
         // verify that we can't turn on biased locking when
         // using rtm locking
         CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
-                "false", "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
+                "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
+                "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
     }
 
     public static void main(String args[]) throws Throwable {
--- a/hotspot/test/gc/g1/TestHumongousShrinkHeap.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/gc/g1/TestHumongousShrinkHeap.java	Wed Jul 05 20:00:07 2017 +0200
@@ -22,9 +22,8 @@
  */
 
 /**
- * @ignore 8041506, 8041946, 8042051
  * @test TestHumongousShrinkHeap
- * @bug 8036025
+ * @bug 8036025 8056043
  * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
  * @library /testlibrary
  * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap
--- a/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Wed Jul 05 20:00:07 2017 +0200
@@ -129,8 +129,19 @@
         return list;
     }
 
+    /**
+     * Verifies that the given list contains expected number of unique strings.
+     * It's possible that deduplication hasn't completed yet, so the method
+     * will perform several attempts to check with a little pause between.
+     * The method throws RuntimeException to signal that verification failed.
+     *
+     * @param list strings to check
+     * @param uniqueExpected expected number of unique strings
+     * @throws RuntimeException if check fails
+     */
     private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
-        for (;;) {
+        boolean passed = false;
+        for (int attempts = 0; attempts < 10; attempts++) {
             // Check number of deduplicated strings
             ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected);
             for (String string: list) {
@@ -153,11 +164,11 @@
                                ", uniqueExpected=" + uniqueExpected);
 
             if (unique.size() == uniqueExpected) {
-                System.out.println("Deduplication completed");
+                System.out.println("Deduplication completed (as fast as " + attempts + " iterations)");
+                passed = true;
                 break;
             } else {
                 System.out.println("Deduplication not completed, waiting...");
-
                 // Give the deduplication thread time to complete
                 try {
                     Thread.sleep(1000);
@@ -166,6 +177,9 @@
                 }
             }
         }
+        if (!passed) {
+            throw new RuntimeException("String verification failed");
+        }
     }
 
     private static OutputAnalyzer runTest(String... extraArgs) throws Exception {
@@ -247,14 +261,20 @@
             forceDeduplication(ageThreshold, FullGC);
 
             // Wait for deduplication to occur
-            while (getValue(dupString1) != getValue(baseString)) {
+            for (int attempts = 0; attempts < 10; attempts++) {
+                if (getValue(dupString1) == getValue(baseString)) {
+                    break;
+                }
                 System.out.println("Waiting...");
                 try {
-                    Thread.sleep(100);
+                    Thread.sleep(1000);
                 } catch (Exception e) {
                     throw new RuntimeException(e);
                 }
             }
+            if (getValue(dupString1) != getValue(baseString)) {
+                throw new RuntimeException("Deduplication has not occurred");
+            }
 
             // Create a new duplicate of baseString
             StringBuilder sb2 = new StringBuilder(baseString);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/whitebox/TestWBGC.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, 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 TestWBGC
+ * @bug 8055098
+ * @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly.
+ * @library /testlibrary /testlibrary/whitebox
+ * @build TestWBGC
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver TestWBGC
+ */
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class TestWBGC {
+
+    public static void main(String args[]) throws Exception {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                true,
+                "-Xbootclasspath/a:.",
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+WhiteBoxAPI",
+                "-XX:MaxTenuringThreshold=1",
+                "-XX:+PrintGC",
+                GCYoungTest.class.getName());
+
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        System.out.println(output.getStdout());
+        output.shouldHaveExitValue(0);
+        output.shouldContain("WhiteBox Initiated Young GC");
+        output.shouldNotContain("Full");
+        // To be sure that we don't provoke Full GC additionaly to young
+    }
+
+    public static class GCYoungTest {
+        static WhiteBox wb = WhiteBox.getWhiteBox();
+        public static Object obj;
+
+        public static void main(String args[]) {
+            obj = new Object();
+            Asserts.assertFalse(wb.isObjectInOldGen(obj));
+            wb.youngGC();
+            wb.youngGC();
+            // 2 young GC is needed to promote object into OldGen
+            Asserts.assertTrue(wb.isObjectInOldGen(obj));
+        }
+    }
+}
--- a/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassPointers.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,6 @@
  * @bug 8024927
  * @summary Testing address of compressed class pointer space as best as possible.
  * @library /testlibrary
- * @ignore 8055164
  */
 
 import com.oracle.java.testlibrary.*;
@@ -89,7 +88,6 @@
             "-version");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("HeapBaseMinAddress must be at least");
-        output.shouldContain("HotSpot");
         output.shouldHaveExitValue(0);
     }
 
--- a/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/CommandLineEmptyArgument.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,6 @@
  * @key nmt
  * @summary Empty argument to NMT should result in an informative error message
  * @library /testlibrary
- * @ignore 8055051
  */
 
 import com.oracle.java.testlibrary.*;
--- a/hotspot/test/runtime/NMT/JcmdDetailDiff.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/JcmdDetailDiff.java	Wed Jul 05 20:00:07 2017 +0200
@@ -62,21 +62,18 @@
 
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
-        output.shouldContain("WB_NMTReserveMemory");
 
         wb.NMTCommitMemory(addr, commitSize);
         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
 
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Test (reserved=256KB +256KB, committed=128KB +128KB)");
-        output.shouldContain("WB_NMTReserveMemory");
 
         wb.NMTUncommitMemory(addr, commitSize);
         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
 
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
-        output.shouldContain("WB_NMTReserveMemory");
 
         wb.NMTReleaseMemory(addr, reserveSize);
         pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
--- a/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java	Wed Jul 05 20:00:07 2017 +0200
@@ -22,10 +22,9 @@
  */
 
 /*
- * @key stress
  * @test
  * @summary Test corner case that overflows malloc site hashtable bucket
- * @key nmt jcmd
+ * @key nmt jcmd stress
  * @library /testlibrary /testlibrary/whitebox
  * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
  * @build MallocSiteHashOverflow
--- a/hotspot/test/runtime/NMT/MallocStressTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/MallocStressTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -22,10 +22,9 @@
  */
 
 /*
- * @key stress
  * @test
  * @summary Stress test for malloc tracking
- * @key nmt jcmd
+ * @key nmt jcmd stress
  * @library /testlibrary /testlibrary/whitebox
  * @build MallocStressTest
  * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
--- a/hotspot/test/runtime/NMT/NMTWithCDS.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/NMTWithCDS.java	Wed Jul 05 20:00:07 2017 +0200
@@ -34,14 +34,15 @@
 
   public static void main(String[] args) throws Exception {
     ProcessBuilder pb;
-    pb = ProcessTools.createJavaProcessBuilder("-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
+    pb = ProcessTools.createJavaProcessBuilder(
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
     try {
       output.shouldContain("Loading classes to share");
       output.shouldHaveExitValue(0);
 
       pb = ProcessTools.createJavaProcessBuilder(
-        "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
+        "-XX:+UnlockDiagnosticVMOptions", "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
       output = new OutputAnalyzer(pb.start());
       output.shouldContain("sharing");
       output.shouldHaveExitValue(0);
--- a/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,6 @@
  * @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly
  * @key nmt jcmd
  * @library /testlibrary /testlibrary/whitebox
- * @ignore
  * @build VirtualAllocCommitUncommitRecommit
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitUncommitRecommit
@@ -43,8 +42,8 @@
 
     public static void main(String args[]) throws Exception {
         OutputAnalyzer output;
-        long commitSize = 4 * 1024; // 4KB
-        long reserveSize = 1024 * 1024; // 1024KB
+        long commitSize = 128 * 1024; // 128KB
+        long reserveSize = 4 * 1024 * 1024; // 4096KB
         long addr;
 
         String pid = Integer.toString(ProcessTools.getProcessId());
@@ -63,11 +62,11 @@
                 "VM.native_memory", "detail" });
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=0KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=0KB)");
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         long addrA = addr;
@@ -84,24 +83,24 @@
         wb.NMTCommitMemory(addrD, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=16KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=512KB)");
 
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
         // uncommit BC
         wb.NMTUncommitMemory(addrB, commitSize);
         wb.NMTUncommitMemory(addrC, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=8KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=256KB)");
 
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         // commit EF
@@ -109,22 +108,22 @@
         wb.NMTCommitMemory(addrF, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=16KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=512KB)");
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         // uncommit A
         wb.NMTUncommitMemory(addrA, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=12KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=384KB)");
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         // commit ABC
@@ -133,11 +132,11 @@
         wb.NMTCommitMemory(addrC, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=24KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=768KB)");
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         // uncommit ABCDEF
@@ -149,11 +148,11 @@
         wb.NMTUncommitMemory(addrF, commitSize);
 
         output = new OutputAnalyzer(pb.start());
-        output.shouldContain("Test (reserved=1024KB, committed=0KB)");
+        output.shouldContain("Test (reserved=4096KB, committed=0KB)");
         if (has_nmt_detail) {
             output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
                     + Long.toHexString(addr + reserveSize)
-                    + "\\] reserved 1024KB for Test");
+                    + "\\] reserved 4096KB for Test");
         }
 
         // release
@@ -161,6 +160,6 @@
         output = new OutputAnalyzer(pb.start());
         output.shouldNotContain("Test (reserved=");
         output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
-                + Long.toHexString(addr + reserveSize) + "\\] reserved");
+                + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
     }
 }
--- a/hotspot/test/runtime/jsig/Test8017498.sh	Wed Jul 05 19:59:05 2017 +0200
+++ b/hotspot/test/runtime/jsig/Test8017498.sh	Wed Jul 05 20:00:07 2017 +0200
@@ -31,15 +31,14 @@
 ## @bug 8022301
 ## @bug 8025519
 ## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
-## @ignore 8041727
 ## @run shell/timeout=60 Test8017498.sh
 ##
 
-if [ "${TESTSRC}" = "" ]
-then
-  TESTSRC=${PWD}
+if [ -z "${TESTSRC}" ]; then
+  TESTSRC="${PWD}"
   echo "TESTSRC not set.  Using "${TESTSRC}" as default"
 fi
+
 echo "TESTSRC=${TESTSRC}"
 ## Adding common setup Variables for running shell tests.
 . ${TESTSRC}/../../test_env.sh
@@ -52,13 +51,13 @@
   Linux)
     echo "Testing on Linux"
     gcc_cmd=`which gcc`
-    if [ "x$gcc_cmd" == "x" ]; then
+    if [ -z "$gcc_cmd" ]; then
         echo "WARNING: gcc not found. Cannot execute test." 2>&1
         exit 0;
     fi
     MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}${VM_CPU}${FS}libjsig.so
-    if [ "$VM_BITS" == "32" ] && [ "$VM_CPU" != "arm" ] && [ "$VM_CPU" != "ppc" ]; then
-            EXTRA_CFLAG=-m32
+    if [ "$VM_BITS" = "32" ] && [ "$VM_CPU" != "arm" ] && [ "$VM_CPU" != "ppc" ]; then
+        EXTRA_CFLAG=-m32
     fi
     echo MY_LD_PRELOAD = ${MY_LD_PRELOAD}
     ;;
@@ -70,7 +69,7 @@
 
 THIS_DIR=.
 
-cp ${TESTSRC}${FS}*.java ${THIS_DIR}
+cp "${TESTSRC}${FS}"*.java "${THIS_DIR}"
 ${COMPILEJAVA}${FS}bin${FS}javac *.java
 
 $gcc_cmd -DLINUX -fPIC -shared \
@@ -80,16 +79,19 @@
     -I${COMPILEJAVA}${FS}include${FS}linux \
     ${TESTSRC}${FS}TestJNI.c
 
+if [ $? -ne 0 ] ; then
+    echo "Compile failed, Ignoring failed compilation and forcing the test to pass"
+    exit 0
+fi
+
 # run the java test in the background
 cmd="LD_PRELOAD=$MY_LD_PRELOAD \
     ${TESTJAVA}${FS}bin${FS}java \
     -Djava.library.path=. -server TestJNI 100"
-echo "$cmd > test.out 2>&1"
-eval $cmd > test.out 2>&1
+echo "$cmd > test.out"
+eval $cmd > test.out
 
-grep "old handler" test.out > ${NULL}
-if [ $? = 0 ]
-then
+if grep "old handler" test.out > ${NULL}; then
     echo "Test Passed"
     exit 0
 fi
--- a/jaxp/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/jaxp/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -271,3 +271,4 @@
 a5aea8318ae4a9c2105228568688875142d70344 jdk9-b26
 2bfaf29cc90b19948938e3ef1a0983eee68806c7 jdk9-b27
 dc1e26434b3fd7e9b8eeab149103c1e30965f95c jdk9-b28
+30adcd13a313ea91e81164801a2f89282756d933 jdk9-b29
--- a/jaxws/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/jaxws/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -274,3 +274,4 @@
 9b43f3993b96c2213428e95127a2d3fd0e709d3a jdk9-b26
 dcaa586ab756420e9a62643793bacef2c84bf637 jdk9-b27
 5282a14f131f897cc9575872c0fae72d47dc4e65 jdk9-b28
+3d1a4bfb6abbf5011ba6d8896301ee3b6ef3ba72 jdk9-b29
--- a/jdk/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -271,3 +271,4 @@
 dde9f5cfde5f46e62ceb5fab81151578e5277aef jdk9-b26
 f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27
 1828f73b35cfe35e460e41fd6e087ab1f83e0621 jdk9-b28
+2da27e8e2c865e154f0c2eb9009f011a44649b11 jdk9-b29
--- a/jdk/make/CreateJars.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/CreateJars.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -76,13 +76,24 @@
     iw ja ko lt lv mk ms mt nl no pl pt ro ru sk sl sq sr sv \
     th tr uk vi zh
 
-LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \
+LOCALEDATA_INCLUDES := sun/util/resources/provider/NonEnLocaleDataMetaInfo.class
+LOCALEDATA_INCLUDES += $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \
     $(addprefix sun/util/resources/, $(LOCALEDATA_INCLUDE_LOCALES))
 
-$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, , \
-    SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata, \
+LOCALEDATA_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/localemetainfo
+
+LOCALEDATA_METAINF_SERVICES := $(LOCALEDATA_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
+
+$(LOCALEDATA_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/localedata-services/sun.util.locale.provider.LocaleDataMetaInfo
+	$(install-file)
+
+$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, \
+    $(LOCALEDATA_METAINF_SERVICES), \
+    SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
+        $(LOCALEDATA_SERVICES_DIR), \
     SUFFIXES := .class _dict _th, \
     INCLUDES := $(LOCALEDATA_INCLUDES), \
+    EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
     JAR := $(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar, \
     SKIP_METAINF := true))
 
@@ -210,6 +221,8 @@
     sun/tools/tree \
     sun/tools/util \
     sun/util/cldr/CLDRLocaleDataMetaInfo.class \
+    sun/util/resources/provider/NonEnLocaleDataMetaInfo.class \
+    META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo \
     sun/util/resources/cldr \
     $(LOCALEDATA_INCLUDES) \
     com/oracle/jrockit/jfr \
@@ -429,13 +442,23 @@
 
 CLDRDATA_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar
 
-$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, , \
+CLDR_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/cldrmetainfo
+
+CLDR_METAINF_SERVICES := $(CLDR_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
+
+$(CLDR_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo
+	$(install-file)
+
+$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, \
+    $(CLDR_METAINF_SERVICES), \
     SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
-        $(JDK_OUTPUTDIR)/modules/java.base, \
+        $(JDK_OUTPUTDIR)/modules/java.base \
+        $(CLDR_SERVICES_DIR), \
     SUFFIXES := .class, \
     INCLUDES := sun/text/resources/cldr \
         sun/util/cldr/CLDRLocaleDataMetaInfo.class \
         sun/util/resources/cldr, \
+    EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
     JAR := $(CLDRDATA_JAR_DST), \
     EXTRA_MANIFEST_ATTR := CLDR-Version: $(CLDRVERSION), \
     SKIP_METAINF := true))
--- a/jdk/make/copy/Copy-java.desktop.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/copy/Copy-java.desktop.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -43,25 +43,6 @@
 
 ################################################################################
 
-ICCPROFILE_DEST_DIR := $(LIB_DST_DIR)/cmm
-
-ifdef OPENJDK
-  ICCPROFILE_SRC_DIR := $(JDK_TOPDIR)/src/java.desktop/share/conf/cmm/lcms
-else
-  ICCPROFILE_SRC_DIR := $(JDK_TOPDIR)/src/closed/java.desktop/share/conf/cmm/kcms
-endif
-
-ICCPROFILE_SRCS := $(wildcard $(ICCPROFILE_SRC_DIR)/*.pf)
-ICCPROFILE_TARGET_FILES := $(subst $(ICCPROFILE_SRC_DIR),$(ICCPROFILE_DEST_DIR),$(ICCPROFILE_SRCS))
-
-$(ICCPROFILE_DEST_DIR)%.pf: $(ICCPROFILE_SRC_DIR)%.pf
-	$(call install-file)
-	$(CHMOD) 444 $@
-
-DESKTOP_CONF_FILES += $(ICCPROFILE_TARGET_FILES)
-
-################################################################################
-
 ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
   # We need to bundle the freetype library, so it will be available at runtime as well as link time.
   #
--- a/jdk/make/data/currency/CurrencyData.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/data/currency/CurrencyData.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
 # Version of the currency code information in this class.
 # It is a serial number that accompanies with each amendment.
 
-dataVersion=156
+dataVersion=159
 
 # List of all valid ISO 4217 currency codes.
 # To ensure compatibility, do not remove codes.
@@ -332,7 +332,7 @@
 # LIECHTENSTEIN
 LI=CHF
 # LITHUANIA
-LT=LTL
+LT=LTL;2014-12-31-22-00-00;EUR
 # LUXEMBOURG
 LU=EUR
 # MACAU
--- a/jdk/make/gensrc/GensrcLocaleDataMetaInfo.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/gensrc/GensrcLocaleDataMetaInfo.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -58,7 +58,14 @@
 # Locales that don't have any resource files should be included here.
 ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
 
-SED_ARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
+SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
+SED_NONENARGS := $(SED_ENARGS)
+
+# Fill in the languages and package names
+SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
+    -e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
+SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
+    -e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
 
 # This macro creates a sed expression that substitues for example:
 # #FormatData_ENLocales# with: en% locales.
@@ -78,8 +85,8 @@
   ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
 
   # Don't sed in a space if there are no locales.
-  SED_ARGS += -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
-  SED_ARGS += -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
+  SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
+  SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
 endef
 
 #sun.text.resources.FormatData
@@ -106,17 +113,25 @@
 #sun.util.resources.CalendarData
 $(eval $(call CaptureLocale,CalendarData))
 
-SED_ARGS += -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
-SED_ARGS += -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
+SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
+SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
 
-$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java: \
+$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
     $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
 	$(MKDIR) -p $(@D)
-	$(ECHO) Creating sun/util/LocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
+	$(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
 	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
-	$(SED) $(SED_ARGS) $< > $@
+	$(SED) $(SED_ENARGS) $< > $@
 
-GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java
+$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
+    $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
+	$(MKDIR) -p $(@D)
+	$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
+	$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
+	$(SED) $(SED_NONENARGS) $< > $@
+
+GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java \
+    $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
 
 ################################################################################
 
--- a/jdk/make/profile-includes.txt	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/profile-includes.txt	Wed Jul 05 20:00:07 2017 +0200
@@ -168,11 +168,6 @@
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \
     $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \
     charsets.jar \
-    cmm/CIEXYZ.pf \
-    cmm/GRAY.pf \
-    cmm/LINEAR_RGB.pf \
-    cmm/PYCC.pf \
-    cmm/sRGB.pf \
     ext/cldrdata.jar \
     ext/dnsns.jar \
     ext/nashorn.jar \
--- a/jdk/make/src/classes/build/tools/cldrconverter/CLDRConverter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/src/classes/build/tools/cldrconverter/CLDRConverter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -431,7 +431,7 @@
             allLocales.addAll(metaInfo.get("LocaleNames"));
             allLocales.addAll(metaInfo.get("CalendarData"));
             allLocales.addAll(metaInfo.get("FormatData"));
-            metaInfo.put("All", allLocales);
+            metaInfo.put("AvailableLocales", allLocales);
         }
 
         bundleGenerator.generateMetaInfo(metaInfo);
--- a/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/make/src/classes/build/tools/cldrconverter/ResourceBundleGenerator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -159,8 +159,10 @@
             out.println(CopyrightHeaders.getOpenJDKCopyright());
 
             out.println("package sun.util.cldr;\n\n"
-                      + "import java.util.ListResourceBundle;\n");
-            out.printf("public class %s extends ListResourceBundle {\n", METAINFO_CLASS);
+                      + "import java.util.ListResourceBundle;\n"
+                      + "import sun.util.locale.provider.LocaleProviderAdapter;\n"
+                      + "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
+            out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", METAINFO_CLASS);
             out.println("    @Override\n" +
                         "    protected final Object[][] getContents() {\n" +
                         "        final Object[][] data = new Object[][] {");
@@ -168,7 +170,15 @@
                 out.printf("            { \"%s\",\n", key);
                 out.printf("              \"%s\" },\n", toLocaleList(metaInfo.get(key)));
             }
-            out.println("        };\n        return data;\n    }\n}");
+            out.println("        };\n        return data;\n    }\n\n");
+
+            out.println("    public LocaleProviderAdapter.Type getType() {\n" +
+                        "        return LocaleProviderAdapter.Type.CLDR;\n" +
+                        "    }\n\n");
+
+            out.println("    public String availableLanguageTags(String category) {\n" +
+                        "        return getString(category);\n" +
+                        "    };\n}");
         }
     }
 
--- a/jdk/src/demo/share/java2d/J2DBench/Makefile	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/Makefile	Wed Jul 05 20:00:07 2017 +0200
@@ -72,6 +72,7 @@
 
 J2DBENCH_RESOURCES = \
 	$(CLASSES)/j2dbench/tests/iio/images \
+	$(CLASSES)/j2dbench/tests/cmm/images \
 	$(CLASSES)/j2dbench/tests/text/textdata
 
 SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
@@ -101,6 +102,10 @@
 	cp -r $< $@
 	cd $@ && rm -rf $(SCM_DIRs)
 
+$(CLASSES)/j2dbench/tests/cmm/images: $(RESOURCES)/cmm_images
+	cp -r $< $@
+	cd $@ && rm -rf $(SCM_DIRs)
+
 $(CLASSES)/j2dbench.manifest:
 	echo "Main-Class: j2dbench.J2DBench" > $@
 
@@ -115,7 +120,7 @@
 mkdirs: $(DIST) $(CLASSES)
 
 $(CLASSES)/j2dbench/%.class: $(SOURCEPATH)/j2dbench/%.java
-	javac -source 1.2 -target 1.2 -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
+	javac -g:none -source 1.6 -target 1.6 -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
 
 clean:
 	rm -rf $(CLASSES)
--- a/jdk/src/demo/share/java2d/J2DBench/README	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/README	Wed Jul 05 20:00:07 2017 +0200
@@ -19,10 +19,9 @@
 Minimum requirements
 -----------------------------------------------------------------------
 
-The benchmark requires at least jdk1.4 to compile and
-at least jdk1.2** to run.
-
-** Note: the goal is to make the benchmark run on 1.1.x as well.
+The benchmark requires at least jdk1.4 to compile and run. Note that
+source/target is set to 1.6 in the makefile and build.xml, because of
+support in jdk 9 compiler.
 
 -----------------------------------------------------------------------
 How To Compile
@@ -125,7 +124,7 @@
 
 After the options file is created, start J2DBench in batch mode to run
 the benchmarks for the default pipeline:
-#> java -jar dest/J2DBench.jar -batch -loadopts options/default.opt \
+#> java -jar dist/J2DBench.jar -batch -loadopts options/default.opt \
      -saveres default.res -title "Rendering - Default ppl" \
      -desc "Rendering tests with the default pipeline"
 
@@ -136,13 +135,13 @@
 "Run Tests" in the J2DBench dialog)
 
 Now run the benchmark with opengl pipeline:
-#> java -Dsun.java2d.opengl=True -jar dest/J2DBench.jar -batch \
+#> java -Dsun.java2d.opengl=True -jar dist/J2DBench.jar -batch \
      -loadopts options/default.opt \
      -saveres opengl.res -title "Rendering - OpenGL" \
      -desc "Rendering tests with OpenGL pipeline"
 
 Now let's analyze the results using J2DAnalyzer:
-#> java -jar dest/J2DAnalyzer.jar default.res opengl.res
+#> java -jar dist/J2DAnalyzer.jar default.res opengl.res
 
 Note that you can compare more than two sets of results, see
 J2DAnalyzer's help page.
--- a/jdk/src/demo/share/java2d/J2DBench/build.xml	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/build.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -49,7 +49,7 @@
   <target name="compile" depends="init"
         description="compile the source " >
     <!-- Compile the java code from ${src} into ${build} -->
-    <javac debug="flase" source="1.5" target="1.5" srcdir="${src}" destdir="${build}"/>
+    <javac debug="off" source="1.6" target="1.6" srcdir="${src}" destdir="${build}"/>
   </target>
 
   <target name="run" depends="dist"
--- a/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/CMMTests.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/CMMTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,23 +39,24 @@
 
 package j2dbench.tests.cmm;
 
-import j2dbench.Group;
-import j2dbench.Option;
-import j2dbench.Result;
-import j2dbench.Test;
-import j2dbench.TestEnvironment;
 import java.awt.color.ColorSpace;
 import java.awt.color.ICC_ColorSpace;
 import java.awt.color.ICC_Profile;
 import java.io.IOException;
 import java.io.InputStream;
 
+import j2dbench.Group;
+import j2dbench.Option;
+import j2dbench.Result;
+import j2dbench.Test;
+import j2dbench.TestEnvironment;
+
 public class CMMTests extends Test {
 
     protected static Group cmmRoot;
     protected static Group cmmOptRoot;
     protected static Option csList;
-    protected static Option usePlatfromProfiles;
+    protected static Option usePlatformProfiles;
 
     public static void init() {
         cmmRoot = new Group("cmm", "Color Management Benchmarks");
@@ -64,9 +65,9 @@
         cmmOptRoot = new Group(cmmRoot, "opts", "General Options");
 
         /*
-        usePlatfromProfiles =
-                new Option.Enable(cmmOptRoot, "csPlatfrom",
-                        "Use Platfrom Profiles", false);
+        usePlatformProfiles =
+                new Option.Enable(cmmOptRoot, "csPlatform",
+                        "Use Platform Profiles", false);
         */
         int[] colorspaces = new int[] {
             ColorSpace.CS_sRGB,
@@ -92,10 +93,10 @@
 
     protected static ColorSpace getColorSpace(TestEnvironment env) {
         ColorSpace cs;
-        Boolean usePlatfrom = true; //(Boolean)env.getModifier(usePlatfromProfiles);
+        boolean usePlatform = true; //(Boolean)env.getModifier(usePlatformProfiles);
 
         int cs_code = env.getIntValue(csList);
-        if (usePlatfrom) {
+        if (usePlatform) {
             cs = ColorSpace.getInstance(cs_code);
         } else {
             String resource = "profiles/";
@@ -136,17 +137,14 @@
         addDependencies(cmmOptRoot, true);
     }
 
-    @Override
     public Object initTest(TestEnvironment te, Result result) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
     public void runTest(Object o, int i) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
 
-    @Override
     public void cleanupTest(TestEnvironment te, Object o) {
         throw new UnsupportedOperationException("Not supported yet.");
     }
--- a/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConvertOpTests.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConvertOpTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,11 +39,6 @@
 
 package j2dbench.tests.cmm;
 
-import j2dbench.Group;
-import j2dbench.Option;
-import j2dbench.Result;
-import j2dbench.TestEnvironment;
-import j2dbench.tests.iio.IIOTests;
 import java.awt.AlphaComposite;
 import java.awt.Color;
 import java.awt.Graphics2D;
@@ -53,15 +48,22 @@
 import java.awt.image.ColorConvertOp;
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
+
 import javax.imageio.ImageIO;
 
+import j2dbench.Group;
+import j2dbench.Option;
+import j2dbench.Result;
+import j2dbench.TestEnvironment;
+import j2dbench.tests.iio.IIOTests;
+
 public class ColorConvertOpTests extends ColorConversionTests {
 
-    private static enum ImageContent {
-        BLANK("bank", "Blank (opaque black)"),
-        RANDOM("random", "Random"),
-        VECTOR("vector", "Vector Art"),
-        PHOTO("photo", "Photograph");
+    private static class ImageContent {
+        static ImageContent BLANK = new ImageContent("bank", "Blank (opaque black)");
+        static ImageContent RANDOM = new ImageContent("random", "Random");
+        static ImageContent VECTOR = new ImageContent("vector", "Vector Art");
+        static ImageContent PHOTO= new ImageContent("photo", "Photograph");
 
         public final String name;
         public final String descr;
@@ -70,15 +72,19 @@
             this.name = name;
             this.descr = descr;
         }
+
+        public static ImageContent[] values() {
+            return new ImageContent[]{BLANK, RANDOM, VECTOR, PHOTO};
+        }
     }
 
-    private static enum ImageType {
-        INT_ARGB(BufferedImage.TYPE_INT_ARGB, "INT_ARGB", "TYPE_INT_ARGB"),
-        INT_RGB(BufferedImage.TYPE_INT_RGB, "INT_RGB", "TYPE_INT_RGB"),
-        INT_BGR(BufferedImage.TYPE_INT_BGR, "INT_BGR", "TYPE_INT_BGR"),
-        BYTE_3BYTE_BGR(BufferedImage.TYPE_3BYTE_BGR, "3BYTE_BGR", "TYPE_3BYTE_BGR"),
-        BYTE_4BYTE_ABGR(BufferedImage.TYPE_4BYTE_ABGR, "4BYTE_BGR", "TYPE_4BYTE_BGR"),
-        COMPATIBLE_DST(0, "Compatible", "Compatible destination");
+    private static class ImageType {
+        static ImageType INT_ARGB = new ImageType(BufferedImage.TYPE_INT_ARGB, "INT_ARGB", "TYPE_INT_ARGB");
+        static ImageType INT_RGB = new ImageType(BufferedImage.TYPE_INT_RGB, "INT_RGB", "TYPE_INT_RGB");
+        static ImageType INT_BGR = new ImageType(BufferedImage.TYPE_INT_BGR, "INT_BGR", "TYPE_INT_BGR");
+        static ImageType BYTE_3BYTE_BGR = new ImageType(BufferedImage.TYPE_3BYTE_BGR, "3BYTE_BGR", "TYPE_3BYTE_BGR");
+        static ImageType BYTE_4BYTE_ABGR = new ImageType(BufferedImage.TYPE_4BYTE_ABGR, "4BYTE_BGR", "TYPE_4BYTE_BGR");
+        static ImageType COMPATIBLE_DST = new ImageType(0, "Compatible", "Compatible destination");
 
         private ImageType(int type, String abbr, String descr) {
             this.type = type;
@@ -89,11 +95,16 @@
         public final int type;
         public final String abbrev;
         public final String descr;
+
+        public static ImageType[] values() {
+            return new ImageType[]{INT_ARGB, INT_RGB, INT_BGR,
+                    BYTE_3BYTE_BGR, BYTE_4BYTE_ABGR, COMPATIBLE_DST};
+        }
     }
 
-    private static enum ListType {
-        SRC("srcType", "Source Images"),
-        DST("dstType", "Destination Images");
+    private static class ListType {
+        static ListType SRC = new ListType("srcType", "Source Images");
+        static ListType DST = new ListType("dstType", "Destination Images");
 
         private ListType(String name, String description) {
             this.name = name;
@@ -320,64 +331,55 @@
         BufferedImage image;
         image = new BufferedImage(width, height, type);
         boolean hasAlpha = image.getColorModel().hasAlpha();
-        switch (contentType) {
-            case RANDOM:
-                for (int y = 0; y < height; y++) {
-                    for (int x = 0; x < width; x++) {
-                        int rgb = (int)(Math.random() * 0xffffff);
-                        if (hasAlpha) {
-                            rgb |= 0x7f000000;
-                        }
-                        image.setRGB(x, y, rgb);
-                    }
-                }
-                break;
-            case VECTOR:
-                {
-                    Graphics2D g = image.createGraphics();
+        if (contentType == ImageContent.RANDOM) {
+            for (int y = 0; y < height; y++) {
+                for (int x = 0; x < width; x++) {
+                    int rgb = (int) (Math.random() * 0xffffff);
                     if (hasAlpha) {
-                        // fill background with a translucent color
-                        g.setComposite(AlphaComposite.getInstance(
-                                           AlphaComposite.SRC, 0.5f));
+                        rgb |= 0x7f000000;
                     }
-                    g.setColor(Color.blue);
-                    g.fillRect(0, 0, width, height);
-                    g.setComposite(AlphaComposite.Src);
-                    g.setColor(Color.yellow);
-                    g.fillOval(2, 2, width-4, height-4);
-                    g.setColor(Color.red);
-                    g.fillOval(4, 4, width-8, height-8);
-                    g.setColor(Color.green);
-                    g.fillRect(8, 8, width-16, height-16);
-                    g.setColor(Color.white);
-                    g.drawLine(0, 0, width, height);
-                    g.drawLine(0, height, width, 0);
-                    g.dispose();
-                    break;
+                    image.setRGB(x, y, rgb);
                 }
-            case PHOTO:
-                {
-                    Image photo = null;
-                    try {
-                        photo = ImageIO.read(
-                            IIOTests.class.getResourceAsStream("images/photo.jpg"));
-                    } catch (Exception e) {
-                        System.err.println("error loading photo");
-                        e.printStackTrace();
-                    }
-                    Graphics2D g = image.createGraphics();
-                    if (hasAlpha) {
-                        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC,
-                                                                  0.5f));
-                    }
-                    g.drawImage(photo, 0, 0, width, height, null);
-                    g.dispose();
-                    break;
-                }
-            default:
-                break;
+            }
         }
-
+        if (contentType == ImageContent.VECTOR) {
+            Graphics2D g = image.createGraphics();
+            if (hasAlpha) {
+                // fill background with a translucent color
+                g.setComposite(AlphaComposite.getInstance(
+                                   AlphaComposite.SRC, 0.5f));
+            }
+            g.setColor(Color.blue);
+            g.fillRect(0, 0, width, height);
+            g.setComposite(AlphaComposite.Src);
+            g.setColor(Color.yellow);
+            g.fillOval(2, 2, width-4, height-4);
+            g.setColor(Color.red);
+            g.fillOval(4, 4, width-8, height-8);
+            g.setColor(Color.green);
+            g.fillRect(8, 8, width-16, height-16);
+            g.setColor(Color.white);
+            g.drawLine(0, 0, width, height);
+            g.drawLine(0, height, width, 0);
+            g.dispose();
+        }
+        if (contentType == ImageContent.PHOTO) {
+            Image photo = null;
+            try {
+                photo = ImageIO.read(
+                    IIOTests.class.getResourceAsStream("images/photo.jpg"));
+            } catch (Exception e) {
+                System.err.println("error loading photo");
+                e.printStackTrace();
+            }
+            Graphics2D g = image.createGraphics();
+            if (hasAlpha) {
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC,
+                                                          0.5f));
+            }
+            g.drawImage(photo, 0, 0, width, height, null);
+            g.dispose();
+        }
         return image;
     }
 }
--- a/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/DataConversionTests.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/DataConversionTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,10 +39,11 @@
 
 package j2dbench.tests.cmm;
 
+import java.awt.color.ColorSpace;
+
 import j2dbench.Group;
 import j2dbench.Result;
 import j2dbench.TestEnvironment;
-import java.awt.color.ColorSpace;
 
 public class DataConversionTests extends ColorConversionTests {
 
@@ -92,13 +93,11 @@
         }
     }
 
-    @Override
     public Object initTest(TestEnvironment env, Result result) {
         ColorSpace cs = getColorSpace(env);
         return new Context(env, result, cs);
     }
 
-    @Override
     public void cleanupTest(TestEnvironment te, Object o) {
     }
 
--- a/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -39,16 +39,18 @@
 
 package j2dbench.tests.cmm;
 
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.net.URL;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
 import j2dbench.Group;
 import j2dbench.Option;
 import j2dbench.Result;
 import j2dbench.TestEnvironment;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.net.URL;
-import javax.imageio.ImageIO;
-import javax.imageio.ImageReader;
-import javax.imageio.stream.ImageInputStream;
 
 /* This benchmark verifies how changes in cmm library affects image decoding */
 public class EmbeddedProfileTests extends ColorConversionTests {
@@ -68,10 +70,10 @@
         new ReadImageTest();
     }
 
-    private static enum IccImageResource {
-        SMALL("images/img_icc_small.jpg", "512x512", "Small: 512x512"),
-        MEDIUM("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048"),
-        LARGE("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096");
+    private static class IccImageResource {
+        static IccImageResource SMALL = new IccImageResource("images/img_icc_small.jpg", "512x512", "Small: 512x512");
+        static IccImageResource MEDIUM = new IccImageResource("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048");
+        static IccImageResource LARGE = new IccImageResource("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096");
 
         private IccImageResource(String file, String name, String description) {
             this.url = CMMTests.class.getResource(file);
@@ -82,6 +84,10 @@
         public final URL url;
         public final String abbrev;
         public final String description;
+
+        public static IccImageResource[] values() {
+            return new IccImageResource[]{SMALL, MEDIUM, LARGE};
+        }
     }
 
     private static Option createImageList() {
@@ -145,7 +151,7 @@
 
             try {
                 iis = ImageIO.createImageInputStream(url.openStream());
-                reader = ImageIO.getImageReaders(iis).next();
+                reader = (ImageReader) ImageIO.getImageReaders(iis).next();
             } catch (IOException e) {
                 throw new RuntimeException("Unable to run the becnhmark", e);
             }
--- a/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/ProfileTests.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/demo/share/java2d/J2DBench/src/j2dbench/tests/cmm/ProfileTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,12 +38,12 @@
  */
 package j2dbench.tests.cmm;
 
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+
 import j2dbench.Group;
 import j2dbench.Result;
 import j2dbench.TestEnvironment;
-import java.awt.color.ColorSpace;
-import java.awt.color.ICC_ColorSpace;
-import java.awt.color.ICC_Profile;
 
 public class ProfileTests extends CMMTests {
 
@@ -73,13 +73,11 @@
         }
     }
 
-    @Override
     public Object initTest(TestEnvironment env, Result res) {
         ICC_ColorSpace cs = (ICC_ColorSpace) getColorSpace(env);
         return new Context(cs.getProfile(), env, res);
     }
 
-    @Override
     public void cleanupTest(TestEnvironment env, Object o) {
     }
 
@@ -91,7 +89,6 @@
                     "getData(icSigHead)");
         }
 
-        @Override
         public void runTest(Object ctx, int numReps) {
             final Context ictx = (Context) ctx;
             final ICC_Profile profile = ictx.profile;
@@ -115,7 +112,6 @@
                     "getNumComponents");
         }
 
-        @Override
         public void runTest(Object ctx, int numReps) {
             final Context ictx = (Context) ctx;
             final ICC_Profile profile = ictx.profile;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java	Wed Jul 05 20:00:07 2017 +0200
@@ -50,7 +50,6 @@
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletionException;
 import java.util.concurrent.CompletionStage;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.locks.LockSupport;
 
 /**
@@ -77,9 +76,9 @@
  * <li>All <em>async</em> methods without an explicit Executor
  * argument are performed using the {@link ForkJoinPool#commonPool()}
  * (unless it does not support a parallelism level of at least two, in
- * which case, a new Thread is used). To simplify monitoring,
- * debugging, and tracking, all generated asynchronous tasks are
- * instances of the marker interface {@link
+ * which case, a new Thread is created to run each task).  To simplify
+ * monitoring, debugging, and tracking, all generated asynchronous
+ * tasks are instances of the marker interface {@link
  * AsynchronousCompletionTask}. </li>
  *
  * <li>All CompletionStage methods are implemented independently of
@@ -113,141 +112,1556 @@
     /*
      * Overview:
      *
-     * 1. Non-nullness of field result (set via CAS) indicates done.
-     * An AltResult is used to box null as a result, as well as to
-     * hold exceptions.  Using a single field makes completion fast
-     * and simple to detect and trigger, at the expense of a lot of
-     * encoding and decoding that infiltrates many methods. One minor
-     * simplification relies on the (static) NIL (to box null results)
-     * being the only AltResult with a null exception field, so we
-     * don't usually need explicit comparisons with NIL. The CF
-     * exception propagation mechanics surrounding decoding rely on
-     * unchecked casts of decoded results really being unchecked,
-     * where user type errors are caught at point of use, as is
-     * currently the case in Java. These are highlighted by using
-     * SuppressWarnings-annotated temporaries.
+     * A CompletableFuture may have dependent completion actions,
+     * collected in a linked stack. It atomically completes by CASing
+     * a result field, and then pops off and runs those actions. This
+     * applies across normal vs exceptional outcomes, sync vs async
+     * actions, binary triggers, and various forms of completions.
+     *
+     * Non-nullness of field result (set via CAS) indicates done.  An
+     * AltResult is used to box null as a result, as well as to hold
+     * exceptions.  Using a single field makes completion simple to
+     * detect and trigger.  Encoding and decoding is straightforward
+     * but adds to the sprawl of trapping and associating exceptions
+     * with targets.  Minor simplifications rely on (static) NIL (to
+     * box null results) being the only AltResult with a null
+     * exception field, so we don't usually need explicit comparisons.
+     * Even though some of the generics casts are unchecked (see
+     * SuppressWarnings annotations), they are placed to be
+     * appropriate even if checked.
      *
-     * 2. Waiters are held in a Treiber stack similar to the one used
-     * in FutureTask, Phaser, and SynchronousQueue. See their
-     * internal documentation for algorithmic details.
+     * Dependent actions are represented by Completion objects linked
+     * as Treiber stacks headed by field "stack". There are Completion
+     * classes for each kind of action, grouped into single-input
+     * (UniCompletion), two-input (BiCompletion), projected
+     * (BiCompletions using either (not both) of two inputs), shared
+     * (CoCompletion, used by the second of two sources), zero-input
+     * source actions, and Signallers that unblock waiters. Class
+     * Completion extends ForkJoinTask to enable async execution
+     * (adding no space overhead because we exploit its "tag" methods
+     * to maintain claims). It is also declared as Runnable to allow
+     * usage with arbitrary executors.
+     *
+     * Support for each kind of CompletionStage relies on a separate
+     * class, along with two CompletableFuture methods:
+     *
+     * * A Completion class with name X corresponding to function,
+     *   prefaced with "Uni", "Bi", or "Or". Each class contains
+     *   fields for source(s), actions, and dependent. They are
+     *   boringly similar, differing from others only with respect to
+     *   underlying functional forms. We do this so that users don't
+     *   encounter layers of adaptors in common usages. We also
+     *   include "Relay" classes/methods that don't correspond to user
+     *   methods; they copy results from one stage to another.
+     *
+     * * Boolean CompletableFuture method x(...) (for example
+     *   uniApply) takes all of the arguments needed to check that an
+     *   action is triggerable, and then either runs the action or
+     *   arranges its async execution by executing its Completion
+     *   argument, if present. The method returns true if known to be
+     *   complete.
      *
-     * 3. Completions are also kept in a list/stack, and pulled off
-     * and run when completion is triggered. (We could even use the
-     * same stack as for waiters, but would give up the potential
-     * parallelism obtained because woken waiters help release/run
-     * others -- see method postComplete).  Because post-processing
-     * may race with direct calls, class Completion opportunistically
-     * extends AtomicInteger so callers can claim the action via
-     * compareAndSet(0, 1).  The Completion.run methods are all
-     * written a boringly similar uniform way (that sometimes includes
-     * unnecessary-looking checks, kept to maintain uniformity).
-     * There are enough dimensions upon which they differ that
-     * attempts to factor commonalities while maintaining efficiency
-     * require more lines of code than they would save.
+     * * Completion method tryFire(int mode) invokes the associated x
+     *   method with its held arguments, and on success cleans up.
+     *   The mode argument allows tryFire to be called twice (SYNC,
+     *   then ASYNC); the first to screen and trap exceptions while
+     *   arranging to execute, and the second when called from a
+     *   task. (A few classes are not used async so take slightly
+     *   different forms.)  The claim() callback suppresses function
+     *   invocation if already claimed by another thread.
+     *
+     * * CompletableFuture method xStage(...) is called from a public
+     *   stage method of CompletableFuture x. It screens user
+     *   arguments and invokes and/or creates the stage object.  If
+     *   not async and x is already complete, the action is run
+     *   immediately.  Otherwise a Completion c is created, pushed to
+     *   x's stack (unless done), and started or triggered via
+     *   c.tryFire.  This also covers races possible if x completes
+     *   while pushing.  Classes with two inputs (for example BiApply)
+     *   deal with races across both while pushing actions.  The
+     *   second completion is a CoCompletion pointing to the first,
+     *   shared so that at most one performs the action.  The
+     *   multiple-arity methods allOf and anyOf do this pairwise to
+     *   form trees of completions.
+     *
+     * Note that the generic type parameters of methods vary according
+     * to whether "this" is a source, dependent, or completion.
      *
-     * 4. The exported then/and/or methods do support a bit of
-     * factoring (see doThenApply etc). They must cope with the
-     * intrinsic races surrounding addition of a dependent action
-     * versus performing the action directly because the task is
-     * already complete.  For example, a CF may not be complete upon
-     * entry, so a dependent completion is added, but by the time it
-     * is added, the target CF is complete, so must be directly
-     * executed. This is all done while avoiding unnecessary object
-     * construction in safe-bypass cases.
+     * Method postComplete is called upon completion unless the target
+     * is guaranteed not to be observable (i.e., not yet returned or
+     * linked). Multiple threads can call postComplete, which
+     * atomically pops each dependent action, and tries to trigger it
+     * via method tryFire, in NESTED mode.  Triggering can propagate
+     * recursively, so NESTED mode returns its completed dependent (if
+     * one exists) for further processing by its caller (see method
+     * postFire).
+     *
+     * Blocking methods get() and join() rely on Signaller Completions
+     * that wake up waiting threads.  The mechanics are similar to
+     * Treiber stack wait-nodes used in FutureTask, Phaser, and
+     * SynchronousQueue. See their internal documentation for
+     * algorithmic details.
+     *
+     * Without precautions, CompletableFutures would be prone to
+     * garbage accumulation as chains of Completions build up, each
+     * pointing back to its sources. So we null out fields as soon as
+     * possible (see especially method Completion.detach). The
+     * screening checks needed anyway harmlessly ignore null arguments
+     * that may have been obtained during races with threads nulling
+     * out fields.  We also try to unlink fired Completions from
+     * stacks that might never be popped (see method postFire).
+     * Completion fields need not be declared as final or volatile
+     * because they are only visible to other threads upon safe
+     * publication.
      */
 
-    // preliminaries
+    volatile Object result;       // Either the result or boxed AltResult
+    volatile Completion stack;    // Top of Treiber stack of dependent actions
+
+    final boolean internalComplete(Object r) { // CAS from null to r
+        return UNSAFE.compareAndSwapObject(this, RESULT, null, r);
+    }
+
+    final boolean casStack(Completion cmp, Completion val) {
+        return UNSAFE.compareAndSwapObject(this, STACK, cmp, val);
+    }
+
+    /** Returns true if successfully pushed c onto stack. */
+    final boolean tryPushStack(Completion c) {
+        Completion h = stack;
+        lazySetNext(c, h);
+        return UNSAFE.compareAndSwapObject(this, STACK, h, c);
+    }
+
+    /** Unconditionally pushes c onto stack, retrying if necessary. */
+    final void pushStack(Completion c) {
+        do {} while (!tryPushStack(c));
+    }
+
+    /* ------------- Encoding and decoding outcomes -------------- */
+
+    static final class AltResult { // See above
+        final Throwable ex;        // null only for NIL
+        AltResult(Throwable x) { this.ex = x; }
+    }
 
-    static final class AltResult {
-        final Throwable ex; // null only for NIL
-        AltResult(Throwable ex) { this.ex = ex; }
+    /** The encoding of the null value. */
+    static final AltResult NIL = new AltResult(null);
+
+    /** Completes with the null value, unless already completed. */
+    final boolean completeNull() {
+        return UNSAFE.compareAndSwapObject(this, RESULT, null,
+                                           NIL);
+    }
+
+    /** Returns the encoding of the given non-exceptional value. */
+    final Object encodeValue(T t) {
+        return (t == null) ? NIL : t;
+    }
+
+    /** Completes with a non-exceptional result, unless already completed. */
+    final boolean completeValue(T t) {
+        return UNSAFE.compareAndSwapObject(this, RESULT, null,
+                                           (t == null) ? NIL : t);
+    }
+
+    /**
+     * Returns the encoding of the given (non-null) exception as a
+     * wrapped CompletionException unless it is one already.
+     */
+    static AltResult encodeThrowable(Throwable x) {
+        return new AltResult((x instanceof CompletionException) ? x :
+                             new CompletionException(x));
+    }
+
+    /** Completes with an exceptional result, unless already completed. */
+    final boolean completeThrowable(Throwable x) {
+        return UNSAFE.compareAndSwapObject(this, RESULT, null,
+                                           encodeThrowable(x));
     }
 
-    static final AltResult NIL = new AltResult(null);
+    /**
+     * Returns the encoding of the given (non-null) exception as a
+     * wrapped CompletionException unless it is one already.  May
+     * return the given Object r (which must have been the result of a
+     * source future) if it is equivalent, i.e. if this is a simple
+     * relay of an existing CompletionException.
+     */
+    static Object encodeThrowable(Throwable x, Object r) {
+        if (!(x instanceof CompletionException))
+            x = new CompletionException(x);
+        else if (r instanceof AltResult && x == ((AltResult)r).ex)
+            return r;
+        return new AltResult(x);
+    }
 
-    // Fields
+    /**
+     * Completes with the given (non-null) exceptional result as a
+     * wrapped CompletionException unless it is one already, unless
+     * already completed.  May complete with the given Object r
+     * (which must have been the result of a source future) if it is
+     * equivalent, i.e. if this is a simple propagation of an
+     * existing CompletionException.
+     */
+    final boolean completeThrowable(Throwable x, Object r) {
+        return UNSAFE.compareAndSwapObject(this, RESULT, null,
+                                           encodeThrowable(x, r));
+    }
+
+    /**
+     * Returns the encoding of the given arguments: if the exception
+     * is non-null, encodes as AltResult.  Otherwise uses the given
+     * value, boxed as NIL if null.
+     */
+    Object encodeOutcome(T t, Throwable x) {
+        return (x == null) ? (t == null) ? NIL : t : encodeThrowable(x);
+    }
 
-    volatile Object result;    // Either the result or boxed AltResult
-    volatile WaitNode waiters; // Treiber stack of threads blocked on get()
-    volatile CompletionNode completions; // list (Treiber stack) of completions
+    /**
+     * Returns the encoding of a copied outcome; if exceptional,
+     * rewraps as a CompletionException, else returns argument.
+     */
+    static Object encodeRelay(Object r) {
+        Throwable x;
+        return (((r instanceof AltResult) &&
+                 (x = ((AltResult)r).ex) != null &&
+                 !(x instanceof CompletionException)) ?
+                new AltResult(new CompletionException(x)) : r);
+    }
+
+    /**
+     * Completes with r or a copy of r, unless already completed.
+     * If exceptional, r is first coerced to a CompletionException.
+     */
+    final boolean completeRelay(Object r) {
+        return UNSAFE.compareAndSwapObject(this, RESULT, null,
+                                           encodeRelay(r));
+    }
 
-    // Basic utilities for triggering and processing completions
+    /**
+     * Reports result using Future.get conventions.
+     */
+    private static <T> T reportGet(Object r)
+        throws InterruptedException, ExecutionException {
+        if (r == null) // by convention below, null means interrupted
+            throw new InterruptedException();
+        if (r instanceof AltResult) {
+            Throwable x, cause;
+            if ((x = ((AltResult)r).ex) == null)
+                return null;
+            if (x instanceof CancellationException)
+                throw (CancellationException)x;
+            if ((x instanceof CompletionException) &&
+                (cause = x.getCause()) != null)
+                x = cause;
+            throw new ExecutionException(x);
+        }
+        @SuppressWarnings("unchecked") T t = (T) r;
+        return t;
+    }
 
     /**
-     * Removes and signals all waiting threads and runs all completions.
+     * Decodes outcome to return result or throw unchecked exception.
+     */
+    private static <T> T reportJoin(Object r) {
+        if (r instanceof AltResult) {
+            Throwable x;
+            if ((x = ((AltResult)r).ex) == null)
+                return null;
+            if (x instanceof CancellationException)
+                throw (CancellationException)x;
+            if (x instanceof CompletionException)
+                throw (CompletionException)x;
+            throw new CompletionException(x);
+        }
+        @SuppressWarnings("unchecked") T t = (T) r;
+        return t;
+    }
+
+    /* ------------- Async task preliminaries -------------- */
+
+    /**
+     * A marker interface identifying asynchronous tasks produced by
+     * {@code async} methods. This may be useful for monitoring,
+     * debugging, and tracking asynchronous activities.
+     *
+     * @since 1.8
+     */
+    public static interface AsynchronousCompletionTask {
+    }
+
+    private static final boolean useCommonPool =
+        (ForkJoinPool.getCommonPoolParallelism() > 1);
+
+    /**
+     * Default executor -- ForkJoinPool.commonPool() unless it cannot
+     * support parallelism.
+     */
+    private static final Executor asyncPool = useCommonPool ?
+        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
+
+    /** Fallback if ForkJoinPool.commonPool() cannot support parallelism */
+    static final class ThreadPerTaskExecutor implements Executor {
+        public void execute(Runnable r) { new Thread(r).start(); }
+    }
+
+    /**
+     * Null-checks user executor argument, and translates uses of
+     * commonPool to asyncPool in case parallelism disabled.
+     */
+    static Executor screenExecutor(Executor e) {
+        if (!useCommonPool && e == ForkJoinPool.commonPool())
+            return asyncPool;
+        if (e == null) throw new NullPointerException();
+        return e;
+    }
+
+    // Modes for Completion.tryFire. Signedness matters.
+    static final int SYNC   =  0;
+    static final int ASYNC  =  1;
+    static final int NESTED = -1;
+
+    /* ------------- Base Completion classes and operations -------------- */
+
+    @SuppressWarnings("serial")
+    abstract static class Completion extends ForkJoinTask<Void>
+        implements Runnable, AsynchronousCompletionTask {
+        volatile Completion next;      // Treiber stack link
+
+        /**
+         * Performs completion action if triggered, returning a
+         * dependent that may need propagation, if one exists.
+         *
+         * @param mode SYNC, ASYNC, or NESTED
+         */
+        abstract CompletableFuture<?> tryFire(int mode);
+
+        /** Returns true if possibly still triggerable. Used by cleanStack. */
+        abstract boolean isLive();
+
+        public final void run()                { tryFire(ASYNC); }
+        public final boolean exec()            { tryFire(ASYNC); return true; }
+        public final Void getRawResult()       { return null; }
+        public final void setRawResult(Void v) {}
+    }
+
+    static void lazySetNext(Completion c, Completion next) {
+        UNSAFE.putOrderedObject(c, NEXT, next);
+    }
+
+    /**
+     * Pops and tries to trigger all reachable dependents.  Call only
+     * when known to be done.
      */
     final void postComplete() {
-        WaitNode q; Thread t;
-        while ((q = waiters) != null) {
-            if (UNSAFE.compareAndSwapObject(this, WAITERS, q, q.next) &&
-                (t = q.thread) != null) {
-                q.thread = null;
-                LockSupport.unpark(t);
+        /*
+         * On each step, variable f holds current dependents to pop
+         * and run.  It is extended along only one path at a time,
+         * pushing others to avoid unbounded recursion.
+         */
+        CompletableFuture<?> f = this; Completion h;
+        while ((h = f.stack) != null ||
+               (f != this && (h = (f = this).stack) != null)) {
+            CompletableFuture<?> d; Completion t;
+            if (f.casStack(h, t = h.next)) {
+                if (t != null) {
+                    if (f != this) {
+                        pushStack(h);
+                        continue;
+                    }
+                    h.next = null;    // detach
+                }
+                f = (d = h.tryFire(NESTED)) == null ? this : d;
             }
         }
+    }
 
-        CompletionNode h; Completion c;
-        while ((h = completions) != null) {
-            if (UNSAFE.compareAndSwapObject(this, COMPLETIONS, h, h.next) &&
-                (c = h.completion) != null)
-                c.run();
+    /** Traverses stack and unlinks dead Completions. */
+    final void cleanStack() {
+        for (Completion p = null, q = stack; q != null;) {
+            Completion s = q.next;
+            if (q.isLive()) {
+                p = q;
+                q = s;
+            }
+            else if (p == null) {
+                casStack(q, s);
+                q = stack;
+            }
+            else {
+                p.next = s;
+                if (p.isLive())
+                    q = s;
+                else {
+                    p = null;  // restart
+                    q = stack;
+                }
+            }
+        }
+    }
+
+    /* ------------- One-input Completions -------------- */
+
+    /** A Completion with a source, dependent, and executor. */
+    @SuppressWarnings("serial")
+    abstract static class UniCompletion<T,V> extends Completion {
+        Executor executor;                 // executor to use (null if none)
+        CompletableFuture<V> dep;          // the dependent to complete
+        CompletableFuture<T> src;          // source for action
+
+        UniCompletion(Executor executor, CompletableFuture<V> dep,
+                      CompletableFuture<T> src) {
+            this.executor = executor; this.dep = dep; this.src = src;
+        }
+
+        /**
+         * Returns true if action can be run. Call only when known to
+         * be triggerable. Uses FJ tag bit to ensure that only one
+         * thread claims ownership.  If async, starts as task -- a
+         * later call to tryFire will run action.
+         */
+        final boolean claim() {
+            Executor e = executor;
+            if (compareAndSetForkJoinTaskTag((short)0, (short)1)) {
+                if (e == null)
+                    return true;
+                executor = null; // disable
+                e.execute(this);
+            }
+            return false;
+        }
+
+        final boolean isLive() { return dep != null; }
+    }
+
+    /** Pushes the given completion (if it exists) unless done. */
+    final void push(UniCompletion<?,?> c) {
+        if (c != null) {
+            while (result == null && !tryPushStack(c))
+                lazySetNext(c, null); // clear on failure
         }
     }
 
     /**
-     * Triggers completion with the encoding of the given arguments:
-     * if the exception is non-null, encodes it as a wrapped
-     * CompletionException unless it is one already.  Otherwise uses
-     * the given result, boxed as NIL if null.
+     * Post-processing by dependent after successful UniCompletion
+     * tryFire.  Tries to clean stack of source a, and then either runs
+     * postComplete or returns this to caller, depending on mode.
      */
-    final void internalComplete(T v, Throwable ex) {
-        if (result == null)
-            UNSAFE.compareAndSwapObject
-                (this, RESULT, null,
-                 (ex == null) ? (v == null) ? NIL : v :
-                 new AltResult((ex instanceof CompletionException) ? ex :
-                               new CompletionException(ex)));
-        postComplete(); // help out even if not triggered
+    final CompletableFuture<T> postFire(CompletableFuture<?> a, int mode) {
+        if (a != null && a.stack != null) {
+            if (mode < 0 || a.result == null)
+                a.cleanStack();
+            else
+                a.postComplete();
+        }
+        if (result != null && stack != null) {
+            if (mode < 0)
+                return this;
+            else
+                postComplete();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniApply<T,V> extends UniCompletion<T,V> {
+        Function<? super T,? extends V> fn;
+        UniApply(Executor executor, CompletableFuture<V> dep,
+                 CompletableFuture<T> src,
+                 Function<? super T,? extends V> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniApply(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniApply(CompletableFuture<S> a,
+                               Function<? super S,? extends T> f,
+                               UniApply<S,T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                completeValue(f.apply(s));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniApplyStage(
+        Executor e, Function<? super T,? extends V> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<V> d =  new CompletableFuture<V>();
+        if (e != null || !d.uniApply(this, f, null)) {
+            UniApply<T,V> c = new UniApply<T,V>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniAccept<T> extends UniCompletion<T,Void> {
+        Consumer<? super T> fn;
+        UniAccept(Executor executor, CompletableFuture<Void> dep,
+                  CompletableFuture<T> src, Consumer<? super T> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniAccept(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniAccept(CompletableFuture<S> a,
+                                Consumer<? super S> f, UniAccept<S> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                f.accept(s);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> uniAcceptStage(Executor e,
+                                                   Consumer<? super T> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.uniAccept(this, f, null)) {
+            UniAccept<T> c = new UniAccept<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniRun<T> extends UniCompletion<T,Void> {
+        Runnable fn;
+        UniRun(Executor executor, CompletableFuture<Void> dep,
+               CompletableFuture<T> src, Runnable fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniRun(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else
+                try {
+                    if (c != null && !c.claim())
+                        return false;
+                    f.run();
+                    completeNull();
+                } catch (Throwable ex) {
+                    completeThrowable(ex);
+                }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> uniRunStage(Executor e, Runnable f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.uniRun(this, f, null)) {
+            UniRun<T> c = new UniRun<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniWhenComplete<T> extends UniCompletion<T,T> {
+        BiConsumer<? super T, ? super Throwable> fn;
+        UniWhenComplete(Executor executor, CompletableFuture<T> dep,
+                        CompletableFuture<T> src,
+                        BiConsumer<? super T, ? super Throwable> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<T> tryFire(int mode) {
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniWhenComplete(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniWhenComplete(CompletableFuture<T> a,
+                                  BiConsumer<? super T,? super Throwable> f,
+                                  UniWhenComplete<T> c) {
+        Object r; T t; Throwable x = null;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    x = ((AltResult)r).ex;
+                    t = null;
+                } else {
+                    @SuppressWarnings("unchecked") T tr = (T) r;
+                    t = tr;
+                }
+                f.accept(t, x);
+                if (x == null) {
+                    internalComplete(r);
+                    return true;
+                }
+            } catch (Throwable ex) {
+                if (x == null)
+                    x = ex;
+            }
+            completeThrowable(x, r);
+        }
+        return true;
+    }
+
+    private CompletableFuture<T> uniWhenCompleteStage(
+        Executor e, BiConsumer<? super T, ? super Throwable> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<T> d = new CompletableFuture<T>();
+        if (e != null || !d.uniWhenComplete(this, f, null)) {
+            UniWhenComplete<T> c = new UniWhenComplete<T>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniHandle<T,V> extends UniCompletion<T,V> {
+        BiFunction<? super T, Throwable, ? extends V> fn;
+        UniHandle(Executor executor, CompletableFuture<V> dep,
+                  CompletableFuture<T> src,
+                  BiFunction<? super T, Throwable, ? extends V> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniHandle(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
     }
 
-    /**
-     * If triggered, helps release and/or process completions.
-     */
-    final void helpPostComplete() {
-        if (result != null)
-            postComplete();
+    final <S> boolean uniHandle(CompletableFuture<S> a,
+                                BiFunction<? super S, Throwable, ? extends T> f,
+                                UniHandle<S,T> c) {
+        Object r; S s; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    x = ((AltResult)r).ex;
+                    s = null;
+                } else {
+                    x = null;
+                    @SuppressWarnings("unchecked") S ss = (S) r;
+                    s = ss;
+                }
+                completeValue(f.apply(s, x));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniHandleStage(
+        Executor e, BiFunction<? super T, Throwable, ? extends V> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<V> d = new CompletableFuture<V>();
+        if (e != null || !d.uniHandle(this, f, null)) {
+            UniHandle<T,V> c = new UniHandle<T,V>(e, d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniExceptionally<T> extends UniCompletion<T,T> {
+        Function<? super Throwable, ? extends T> fn;
+        UniExceptionally(CompletableFuture<T> dep, CompletableFuture<T> src,
+                         Function<? super Throwable, ? extends T> fn) {
+            super(null, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<T> tryFire(int mode) { // never ASYNC
+            // assert mode != ASYNC;
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null || !d.uniExceptionally(a = src, fn, this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniExceptionally(CompletableFuture<T> a,
+                                   Function<? super Throwable, ? extends T> f,
+                                   UniExceptionally<T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) {
+                    if (c != null && !c.claim())
+                        return false;
+                    completeValue(f.apply(x));
+                } else
+                    internalComplete(r);
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<T> uniExceptionallyStage(
+        Function<Throwable, ? extends T> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<T> d = new CompletableFuture<T>();
+        if (!d.uniExceptionally(this, f, null)) {
+            UniExceptionally<T> c = new UniExceptionally<T>(d, this, f);
+            push(c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniRelay<T> extends UniCompletion<T,T> { // for Compose
+        UniRelay(CompletableFuture<T> dep, CompletableFuture<T> src) {
+            super(null, dep, src);
+        }
+        final CompletableFuture<T> tryFire(int mode) {
+            CompletableFuture<T> d; CompletableFuture<T> a;
+            if ((d = dep) == null || !d.uniRelay(a = src))
+                return null;
+            src = null; dep = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final boolean uniRelay(CompletableFuture<T> a) {
+        Object r;
+        if (a == null || (r = a.result) == null)
+            return false;
+        if (result == null) // no need to claim
+            completeRelay(r);
+        return true;
+    }
+
+    @SuppressWarnings("serial")
+    static final class UniCompose<T,V> extends UniCompletion<T,V> {
+        Function<? super T, ? extends CompletionStage<V>> fn;
+        UniCompose(Executor executor, CompletableFuture<V> dep,
+                   CompletableFuture<T> src,
+                   Function<? super T, ? extends CompletionStage<V>> fn) {
+            super(executor, dep, src); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d; CompletableFuture<T> a;
+            if ((d = dep) == null ||
+                !d.uniCompose(a = src, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; fn = null;
+            return d.postFire(a, mode);
+        }
+    }
+
+    final <S> boolean uniCompose(
+        CompletableFuture<S> a,
+        Function<? super S, ? extends CompletionStage<T>> f,
+        UniCompose<S,T> c) {
+        Object r; Throwable x;
+        if (a == null || (r = a.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") S s = (S) r;
+                CompletableFuture<T> g = f.apply(s).toCompletableFuture();
+                if (g.result == null || !uniRelay(g)) {
+                    UniRelay<T> copy = new UniRelay<T>(this, g);
+                    g.push(copy);
+                    copy.tryFire(SYNC);
+                    if (result == null)
+                        return false;
+                }
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <V> CompletableFuture<V> uniComposeStage(
+        Executor e, Function<? super T, ? extends CompletionStage<V>> f) {
+        if (f == null) throw new NullPointerException();
+        Object r; Throwable x;
+        if (e == null && (r = result) != null) {
+            // try to return function result directly
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    return new CompletableFuture<V>(encodeThrowable(x, r));
+                }
+                r = null;
+            }
+            try {
+                @SuppressWarnings("unchecked") T t = (T) r;
+                return f.apply(t).toCompletableFuture();
+            } catch (Throwable ex) {
+                return new CompletableFuture<V>(encodeThrowable(ex));
+            }
+        }
+        CompletableFuture<V> d = new CompletableFuture<V>();
+        UniCompose<T,V> c = new UniCompose<T,V>(e, d, this, f);
+        push(c);
+        c.tryFire(SYNC);
+        return d;
+    }
+
+    /* ------------- Two-input Completions -------------- */
+
+    /** A Completion for an action with two sources */
+    @SuppressWarnings("serial")
+    abstract static class BiCompletion<T,U,V> extends UniCompletion<T,V> {
+        CompletableFuture<U> snd; // second source for action
+        BiCompletion(Executor executor, CompletableFuture<V> dep,
+                     CompletableFuture<T> src, CompletableFuture<U> snd) {
+            super(executor, dep, src); this.snd = snd;
+        }
+    }
+
+    /** A Completion delegating to a BiCompletion */
+    @SuppressWarnings("serial")
+    static final class CoCompletion extends Completion {
+        BiCompletion<?,?,?> base;
+        CoCompletion(BiCompletion<?,?,?> base) { this.base = base; }
+        final CompletableFuture<?> tryFire(int mode) {
+            BiCompletion<?,?,?> c; CompletableFuture<?> d;
+            if ((c = base) == null || (d = c.tryFire(mode)) == null)
+                return null;
+            base = null; // detach
+            return d;
+        }
+        final boolean isLive() {
+            BiCompletion<?,?,?> c;
+            return (c = base) != null && c.dep != null;
+        }
+    }
+
+    /** Pushes completion to this and b unless both done. */
+    final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
+        if (c != null) {
+            Object r;
+            while ((r = result) == null && !tryPushStack(c))
+                lazySetNext(c, null); // clear on failure
+            if (b != null && b != this && b.result == null) {
+                Completion q = (r != null) ? c : new CoCompletion(c);
+                while (b.result == null && !b.tryPushStack(q))
+                    lazySetNext(q, null); // clear on failure
+            }
+        }
+    }
+
+    /** Post-processing after successful BiCompletion tryFire. */
+    final CompletableFuture<T> postFire(CompletableFuture<?> a,
+                                        CompletableFuture<?> b, int mode) {
+        if (b != null && b.stack != null) { // clean second source
+            if (mode < 0 || b.result == null)
+                b.cleanStack();
+            else
+                b.postComplete();
+        }
+        return postFire(a, mode);
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiApply<T,U,V> extends BiCompletion<T,U,V> {
+        BiFunction<? super T,? super U,? extends V> fn;
+        BiApply(Executor executor, CompletableFuture<V> dep,
+                CompletableFuture<T> src, CompletableFuture<U> snd,
+                BiFunction<? super T,? super U,? extends V> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biApply(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
     }
 
-    /* ------------- waiting for completions -------------- */
+    final <R,S> boolean biApply(CompletableFuture<R> a,
+                                CompletableFuture<S> b,
+                                BiFunction<? super R,? super S,? extends T> f,
+                                BiApply<R,S,T> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            if (s instanceof AltResult) {
+                if ((x = ((AltResult)s).ex) != null) {
+                    completeThrowable(x, s);
+                    break tryComplete;
+                }
+                s = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                @SuppressWarnings("unchecked") S ss = (S) s;
+                completeValue(f.apply(rr, ss));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U,V> CompletableFuture<V> biApplyStage(
+        Executor e, CompletionStage<U> o,
+        BiFunction<? super T,? super U,? extends V> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<V> d = new CompletableFuture<V>();
+        if (e != null || !d.biApply(this, b, f, null)) {
+            BiApply<T,U,V> c = new BiApply<T,U,V>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiAccept<T,U> extends BiCompletion<T,U,Void> {
+        BiConsumer<? super T,? super U> fn;
+        BiAccept(Executor executor, CompletableFuture<Void> dep,
+                 CompletableFuture<T> src, CompletableFuture<U> snd,
+                 BiConsumer<? super T,? super U> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biAccept(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S> boolean biAccept(CompletableFuture<R> a,
+                                 CompletableFuture<S> b,
+                                 BiConsumer<? super R,? super S> f,
+                                 BiAccept<R,S> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            if (r instanceof AltResult) {
+                if ((x = ((AltResult)r).ex) != null) {
+                    completeThrowable(x, r);
+                    break tryComplete;
+                }
+                r = null;
+            }
+            if (s instanceof AltResult) {
+                if ((x = ((AltResult)s).ex) != null) {
+                    completeThrowable(x, s);
+                    break tryComplete;
+                }
+                s = null;
+            }
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                @SuppressWarnings("unchecked") S ss = (S) s;
+                f.accept(rr, ss);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U> CompletableFuture<Void> biAcceptStage(
+        Executor e, CompletionStage<U> o,
+        BiConsumer<? super T,? super U> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.biAccept(this, b, f, null)) {
+            BiAccept<T,U> c = new BiAccept<T,U>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
 
-    /** Number of processors, for spin control */
-    static final int NCPU = Runtime.getRuntime().availableProcessors();
+    @SuppressWarnings("serial")
+    static final class BiRun<T,U> extends BiCompletion<T,U,Void> {
+        Runnable fn;
+        BiRun(Executor executor, CompletableFuture<Void> dep,
+              CompletableFuture<T> src,
+              CompletableFuture<U> snd,
+              Runnable fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.biRun(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean biRun(CompletableFuture<?> a, CompletableFuture<?> b,
+                        Runnable f, BiRun<?,?> c) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null || f == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
+                completeThrowable(x, s);
+            else
+                try {
+                    if (c != null && !c.claim())
+                        return false;
+                    f.run();
+                    completeNull();
+                } catch (Throwable ex) {
+                    completeThrowable(ex);
+                }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> biRunStage(Executor e, CompletionStage<?> o,
+                                               Runnable f) {
+        CompletableFuture<?> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.biRun(this, b, f, null)) {
+            BiRun<T,?> c = new BiRun<>(e, d, this, b, f);
+            bipush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class BiRelay<T,U> extends BiCompletion<T,U,Void> { // for And
+        BiRelay(CompletableFuture<Void> dep,
+                CompletableFuture<T> src,
+                CompletableFuture<U> snd) {
+            super(null, dep, src, snd);
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null || !d.biRelay(a = src, b = snd))
+                return null;
+            src = null; snd = null; dep = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    boolean biRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
+        Object r, s; Throwable x;
+        if (a == null || (r = a.result) == null ||
+            b == null || (s = b.result) == null)
+            return false;
+        if (result == null) {
+            if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                completeThrowable(x, r);
+            else if (s instanceof AltResult && (x = ((AltResult)s).ex) != null)
+                completeThrowable(x, s);
+            else
+                completeNull();
+        }
+        return true;
+    }
+
+    /** Recursively constructs a tree of completions. */
+    static CompletableFuture<Void> andTree(CompletableFuture<?>[] cfs,
+                                           int lo, int hi) {
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (lo > hi) // empty
+            d.result = NIL;
+        else {
+            CompletableFuture<?> a, b;
+            int mid = (lo + hi) >>> 1;
+            if ((a = (lo == mid ? cfs[lo] :
+                      andTree(cfs, lo, mid))) == null ||
+                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
+                      andTree(cfs, mid+1, hi)))  == null)
+                throw new NullPointerException();
+            if (!d.biRelay(a, b)) {
+                BiRelay<?,?> c = new BiRelay<>(d, a, b);
+                a.bipush(b, c);
+                c.tryFire(SYNC);
+            }
+        }
+        return d;
+    }
+
+    /* ------------- Projected (Ored) BiCompletions -------------- */
+
+    /** Pushes completion to this and b unless either done. */
+    final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
+        if (c != null) {
+            while ((b == null || b.result == null) && result == null) {
+                if (tryPushStack(c)) {
+                    if (b != null && b != this && b.result == null) {
+                        Completion q = new CoCompletion(c);
+                        while (result == null && b.result == null &&
+                               !b.tryPushStack(q))
+                            lazySetNext(q, null); // clear on failure
+                    }
+                    break;
+                }
+                lazySetNext(c, null); // clear on failure
+            }
+        }
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrApply<T,U extends T,V> extends BiCompletion<T,U,V> {
+        Function<? super T,? extends V> fn;
+        OrApply(Executor executor, CompletableFuture<V> dep,
+                CompletableFuture<T> src,
+                CompletableFuture<U> snd,
+                Function<? super T,? extends V> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<V> tryFire(int mode) {
+            CompletableFuture<V> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orApply(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
 
-    /**
-     * Heuristic spin value for waitingGet() before blocking on
-     * multiprocessors
-     */
-    static final int SPINS = (NCPU > 1) ? 1 << 8 : 0;
+    final <R,S extends R> boolean orApply(CompletableFuture<R> a,
+                                          CompletableFuture<S> b,
+                                          Function<? super R, ? extends T> f,
+                                          OrApply<R,S,T> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    if ((x = ((AltResult)r).ex) != null) {
+                        completeThrowable(x, r);
+                        break tryComplete;
+                    }
+                    r = null;
+                }
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                completeValue(f.apply(rr));
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U extends T,V> CompletableFuture<V> orApplyStage(
+        Executor e, CompletionStage<U> o,
+        Function<? super T, ? extends V> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<V> d = new CompletableFuture<V>();
+        if (e != null || !d.orApply(this, b, f, null)) {
+            OrApply<T,U,V> c = new OrApply<T,U,V>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrAccept<T,U extends T> extends BiCompletion<T,U,Void> {
+        Consumer<? super T> fn;
+        OrAccept(Executor executor, CompletableFuture<Void> dep,
+                 CompletableFuture<T> src,
+                 CompletableFuture<U> snd,
+                 Consumer<? super T> fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orAccept(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final <R,S extends R> boolean orAccept(CompletableFuture<R> a,
+                                           CompletableFuture<S> b,
+                                           Consumer<? super R> f,
+                                           OrAccept<R,S> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        tryComplete: if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult) {
+                    if ((x = ((AltResult)r).ex) != null) {
+                        completeThrowable(x, r);
+                        break tryComplete;
+                    }
+                    r = null;
+                }
+                @SuppressWarnings("unchecked") R rr = (R) r;
+                f.accept(rr);
+                completeNull();
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private <U extends T> CompletableFuture<Void> orAcceptStage(
+        Executor e, CompletionStage<U> o, Consumer<? super T> f) {
+        CompletableFuture<U> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.orAccept(this, b, f, null)) {
+            OrAccept<T,U> c = new OrAccept<T,U>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrRun<T,U> extends BiCompletion<T,U,Void> {
+        Runnable fn;
+        OrRun(Executor executor, CompletableFuture<Void> dep,
+              CompletableFuture<T> src,
+              CompletableFuture<U> snd,
+              Runnable fn) {
+            super(executor, dep, src, snd); this.fn = fn;
+        }
+        final CompletableFuture<Void> tryFire(int mode) {
+            CompletableFuture<Void> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null ||
+                !d.orRun(a = src, b = snd, fn, mode > 0 ? null : this))
+                return null;
+            dep = null; src = null; snd = null; fn = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean orRun(CompletableFuture<?> a, CompletableFuture<?> b,
+                        Runnable f, OrRun<?,?> c) {
+        Object r; Throwable x;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null) || f == null)
+            return false;
+        if (result == null) {
+            try {
+                if (c != null && !c.claim())
+                    return false;
+                if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
+                    completeThrowable(x, r);
+                else {
+                    f.run();
+                    completeNull();
+                }
+            } catch (Throwable ex) {
+                completeThrowable(ex);
+            }
+        }
+        return true;
+    }
+
+    private CompletableFuture<Void> orRunStage(Executor e, CompletionStage<?> o,
+                                               Runnable f) {
+        CompletableFuture<?> b;
+        if (f == null || (b = o.toCompletableFuture()) == null)
+            throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        if (e != null || !d.orRun(this, b, f, null)) {
+            OrRun<T,?> c = new OrRun<>(e, d, this, b, f);
+            orpush(b, c);
+            c.tryFire(SYNC);
+        }
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class OrRelay<T,U> extends BiCompletion<T,U,Object> { // for Or
+        OrRelay(CompletableFuture<Object> dep, CompletableFuture<T> src,
+                CompletableFuture<U> snd) {
+            super(null, dep, src, snd);
+        }
+        final CompletableFuture<Object> tryFire(int mode) {
+            CompletableFuture<Object> d;
+            CompletableFuture<T> a;
+            CompletableFuture<U> b;
+            if ((d = dep) == null || !d.orRelay(a = src, b = snd))
+                return null;
+            src = null; snd = null; dep = null;
+            return d.postFire(a, b, mode);
+        }
+    }
+
+    final boolean orRelay(CompletableFuture<?> a, CompletableFuture<?> b) {
+        Object r;
+        if (a == null || b == null ||
+            ((r = a.result) == null && (r = b.result) == null))
+            return false;
+        if (result == null)
+            completeRelay(r);
+        return true;
+    }
+
+    /** Recursively constructs a tree of completions. */
+    static CompletableFuture<Object> orTree(CompletableFuture<?>[] cfs,
+                                            int lo, int hi) {
+        CompletableFuture<Object> d = new CompletableFuture<Object>();
+        if (lo <= hi) {
+            CompletableFuture<?> a, b;
+            int mid = (lo + hi) >>> 1;
+            if ((a = (lo == mid ? cfs[lo] :
+                      orTree(cfs, lo, mid))) == null ||
+                (b = (lo == hi ? a : (hi == mid+1) ? cfs[hi] :
+                      orTree(cfs, mid+1, hi)))  == null)
+                throw new NullPointerException();
+            if (!d.orRelay(a, b)) {
+                OrRelay<?,?> c = new OrRelay<>(d, a, b);
+                a.orpush(b, c);
+                c.tryFire(SYNC);
+            }
+        }
+        return d;
+    }
+
+    /* ------------- Zero-input Async forms -------------- */
+
+    @SuppressWarnings("serial")
+    static final class AsyncSupply<T> extends ForkJoinTask<Void>
+            implements Runnable, AsynchronousCompletionTask {
+        CompletableFuture<T> dep; Supplier<T> fn;
+        AsyncSupply(CompletableFuture<T> dep, Supplier<T> fn) {
+            this.dep = dep; this.fn = fn;
+        }
+
+        public final Void getRawResult() { return null; }
+        public final void setRawResult(Void v) {}
+        public final boolean exec() { run(); return true; }
+
+        public void run() {
+            CompletableFuture<T> d; Supplier<T> f;
+            if ((d = dep) != null && (f = fn) != null) {
+                dep = null; fn = null;
+                if (d.result == null) {
+                    try {
+                        d.completeValue(f.get());
+                    } catch (Throwable ex) {
+                        d.completeThrowable(ex);
+                    }
+                }
+                d.postComplete();
+            }
+        }
+    }
+
+    static <U> CompletableFuture<U> asyncSupplyStage(Executor e,
+                                                     Supplier<U> f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<U> d = new CompletableFuture<U>();
+        e.execute(new AsyncSupply<U>(d, f));
+        return d;
+    }
+
+    @SuppressWarnings("serial")
+    static final class AsyncRun extends ForkJoinTask<Void>
+            implements Runnable, AsynchronousCompletionTask {
+        CompletableFuture<Void> dep; Runnable fn;
+        AsyncRun(CompletableFuture<Void> dep, Runnable fn) {
+            this.dep = dep; this.fn = fn;
+        }
+
+        public final Void getRawResult() { return null; }
+        public final void setRawResult(Void v) {}
+        public final boolean exec() { run(); return true; }
+
+        public void run() {
+            CompletableFuture<Void> d; Runnable f;
+            if ((d = dep) != null && (f = fn) != null) {
+                dep = null; fn = null;
+                if (d.result == null) {
+                    try {
+                        f.run();
+                        d.completeNull();
+                    } catch (Throwable ex) {
+                        d.completeThrowable(ex);
+                    }
+                }
+                d.postComplete();
+            }
+        }
+    }
+
+    static CompletableFuture<Void> asyncRunStage(Executor e, Runnable f) {
+        if (f == null) throw new NullPointerException();
+        CompletableFuture<Void> d = new CompletableFuture<Void>();
+        e.execute(new AsyncRun(d, f));
+        return d;
+    }
+
+    /* ------------- Signallers -------------- */
 
     /**
-     * Linked nodes to record waiting threads in a Treiber stack.  See
-     * other classes such as Phaser and SynchronousQueue for more
-     * detailed explanation. This class implements ManagedBlocker to
-     * avoid starvation when blocking actions pile up in
-     * ForkJoinPools.
+     * Completion for recording and releasing a waiting thread.  This
+     * class implements ManagedBlocker to avoid starvation when
+     * blocking actions pile up in ForkJoinPools.
      */
-    static final class WaitNode implements ForkJoinPool.ManagedBlocker {
-        long nanos;          // wait time if timed
-        final long deadline; // non-zero if timed
+    @SuppressWarnings("serial")
+    static final class Signaller extends Completion
+        implements ForkJoinPool.ManagedBlocker {
+        long nanos;                    // wait time if timed
+        final long deadline;           // non-zero if timed
         volatile int interruptControl; // > 0: interruptible, < 0: interrupted
         volatile Thread thread;
-        volatile WaitNode next;
-        WaitNode(boolean interruptible, long nanos, long deadline) {
+
+        Signaller(boolean interruptible, long nanos, long deadline) {
             this.thread = Thread.currentThread();
             this.interruptControl = interruptible ? 1 : 0;
             this.nanos = nanos;
             this.deadline = deadline;
         }
+        final CompletableFuture<?> tryFire(int ignore) {
+            Thread w; // no need to atomically claim
+            if ((w = thread) != null) {
+                thread = null;
+                LockSupport.unpark(w);
+            }
+            return null;
+        }
         public boolean isReleasable() {
             if (thread == null)
                 return true;
@@ -273,6 +1687,7 @@
                 LockSupport.parkNanos(this, nanos);
             return isReleasable();
         }
+        final boolean isLive() { return thread != null; }
     }
 
     /**
@@ -280,1832 +1695,89 @@
      * interrupted.
      */
     private Object waitingGet(boolean interruptible) {
-        WaitNode q = null;
+        Signaller q = null;
         boolean queued = false;
-        int spins = SPINS;
-        for (Object r;;) {
-            if ((r = result) != null) {
-                if (q != null) { // suppress unpark
-                    q.thread = null;
-                    if (q.interruptControl < 0) {
-                        if (interruptible) {
-                            removeWaiter(q);
-                            return null;
-                        }
-                        Thread.currentThread().interrupt();
-                    }
-                }
-                postComplete(); // help release others
-                return r;
-            }
+        int spins = -1;
+        Object r;
+        while ((r = result) == null) {
+            if (spins < 0)
+                spins = (Runtime.getRuntime().availableProcessors() > 1) ?
+                    1 << 8 : 0; // Use brief spin-wait on multiprocessors
             else if (spins > 0) {
-                int rnd = ThreadLocalRandom.nextSecondarySeed();
-                if (rnd == 0)
-                    rnd = ThreadLocalRandom.current().nextInt();
-                if (rnd >= 0)
+                if (ThreadLocalRandom.nextSecondarySeed() >= 0)
                     --spins;
             }
             else if (q == null)
-                q = new WaitNode(interruptible, 0L, 0L);
+                q = new Signaller(interruptible, 0L, 0L);
             else if (!queued)
-                queued = UNSAFE.compareAndSwapObject(this, WAITERS,
-                                                     q.next = waiters, q);
+                queued = tryPushStack(q);
             else if (interruptible && q.interruptControl < 0) {
-                removeWaiter(q);
+                q.thread = null;
+                cleanStack();
                 return null;
             }
             else if (q.thread != null && result == null) {
                 try {
                     ForkJoinPool.managedBlock(q);
-                } catch (InterruptedException ex) {
-                    q.interruptControl = -1;
-                }
-            }
-        }
-    }
-
-    /**
-     * Awaits completion or aborts on interrupt or timeout.
-     *
-     * @param nanos time to wait
-     * @return raw result
-     */
-    private Object timedAwaitDone(long nanos)
-        throws InterruptedException, TimeoutException {
-        WaitNode q = null;
-        boolean queued = false;
-        for (Object r;;) {
-            if ((r = result) != null) {
-                if (q != null) {
-                    q.thread = null;
-                    if (q.interruptControl < 0) {
-                        removeWaiter(q);
-                        throw new InterruptedException();
-                    }
-                }
-                postComplete();
-                return r;
-            }
-            else if (q == null) {
-                if (nanos <= 0L)
-                    throw new TimeoutException();
-                long d = System.nanoTime() + nanos;
-                q = new WaitNode(true, nanos, d == 0L ? 1L : d); // avoid 0
-            }
-            else if (!queued)
-                queued = UNSAFE.compareAndSwapObject(this, WAITERS,
-                                                     q.next = waiters, q);
-            else if (q.interruptControl < 0) {
-                removeWaiter(q);
-                throw new InterruptedException();
-            }
-            else if (q.nanos <= 0L) {
-                if (result == null) {
-                    removeWaiter(q);
-                    throw new TimeoutException();
-                }
-            }
-            else if (q.thread != null && result == null) {
-                try {
-                    ForkJoinPool.managedBlock(q);
-                } catch (InterruptedException ex) {
+                } catch (InterruptedException ie) {
                     q.interruptControl = -1;
                 }
             }
         }
-    }
-
-    /**
-     * Tries to unlink a timed-out or interrupted wait node to avoid
-     * accumulating garbage.  Internal nodes are simply unspliced
-     * without CAS since it is harmless if they are traversed anyway
-     * by releasers.  To avoid effects of unsplicing from already
-     * removed nodes, the list is retraversed in case of an apparent
-     * race.  This is slow when there are a lot of nodes, but we don't
-     * expect lists to be long enough to outweigh higher-overhead
-     * schemes.
-     */
-    private void removeWaiter(WaitNode node) {
-        if (node != null) {
-            node.thread = null;
-            retry:
-            for (;;) {          // restart on removeWaiter race
-                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
-                    s = q.next;
-                    if (q.thread != null)
-                        pred = q;
-                    else if (pred != null) {
-                        pred.next = s;
-                        if (pred.thread == null) // check for race
-                            continue retry;
-                    }
-                    else if (!UNSAFE.compareAndSwapObject(this, WAITERS, q, s))
-                        continue retry;
-                }
-                break;
+        if (q != null) {
+            q.thread = null;
+            if (q.interruptControl < 0) {
+                if (interruptible)
+                    r = null; // report interruption
+                else
+                    Thread.currentThread().interrupt();
             }
         }
-    }
-
-    /* ------------- Async tasks -------------- */
-
-    /**
-     * A marker interface identifying asynchronous tasks produced by
-     * {@code async} methods. This may be useful for monitoring,
-     * debugging, and tracking asynchronous activities.
-     *
-     * @since 1.8
-     */
-    public static interface AsynchronousCompletionTask {
-    }
-
-    /** Base class can act as either FJ or plain Runnable */
-    @SuppressWarnings("serial")
-    abstract static class Async extends ForkJoinTask<Void>
-        implements Runnable, AsynchronousCompletionTask {
-        public final Void getRawResult() { return null; }
-        public final void setRawResult(Void v) { }
-        public final void run() { exec(); }
+        postComplete();
+        return r;
     }
 
     /**
-     * Starts the given async task using the given executor, unless
-     * the executor is ForkJoinPool.commonPool and it has been
-     * disabled, in which case starts a new thread.
-     */
-    static void execAsync(Executor e, Async r) {
-        if (e == ForkJoinPool.commonPool() &&
-            ForkJoinPool.getCommonPoolParallelism() <= 1)
-            new Thread(r).start();
-        else
-            e.execute(r);
-    }
-
-    static final class AsyncRun extends Async {
-        final Runnable fn;
-        final CompletableFuture<Void> dst;
-        AsyncRun(Runnable fn, CompletableFuture<Void> dst) {
-            this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<Void> d; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    fn.run();
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-                d.internalComplete(null, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncSupply<U> extends Async {
-        final Supplier<U> fn;
-        final CompletableFuture<U> dst;
-        AsyncSupply(Supplier<U> fn, CompletableFuture<U> dst) {
-            this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<U> d; U u; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    u = fn.get();
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                    u = null;
-                }
-                d.internalComplete(u, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncApply<T,U> extends Async {
-        final T arg;
-        final Function<? super T,? extends U> fn;
-        final CompletableFuture<U> dst;
-        AsyncApply(T arg, Function<? super T,? extends U> fn,
-                   CompletableFuture<U> dst) {
-            this.arg = arg; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<U> d; U u; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    u = fn.apply(arg);
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                    u = null;
-                }
-                d.internalComplete(u, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncCombine<T,U,V> extends Async {
-        final T arg1;
-        final U arg2;
-        final BiFunction<? super T,? super U,? extends V> fn;
-        final CompletableFuture<V> dst;
-        AsyncCombine(T arg1, U arg2,
-                     BiFunction<? super T,? super U,? extends V> fn,
-                     CompletableFuture<V> dst) {
-            this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<V> d; V v; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    v = fn.apply(arg1, arg2);
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                    v = null;
-                }
-                d.internalComplete(v, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncAccept<T> extends Async {
-        final T arg;
-        final Consumer<? super T> fn;
-        final CompletableFuture<?> dst;
-        AsyncAccept(T arg, Consumer<? super T> fn,
-                    CompletableFuture<?> dst) {
-            this.arg = arg; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<?> d; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    fn.accept(arg);
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-                d.internalComplete(null, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncAcceptBoth<T,U> extends Async {
-        final T arg1;
-        final U arg2;
-        final BiConsumer<? super T,? super U> fn;
-        final CompletableFuture<?> dst;
-        AsyncAcceptBoth(T arg1, U arg2,
-                        BiConsumer<? super T,? super U> fn,
-                        CompletableFuture<?> dst) {
-            this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<?> d; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    fn.accept(arg1, arg2);
-                    ex = null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-                d.internalComplete(null, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncCompose<T,U> extends Async {
-        final T arg;
-        final Function<? super T, ? extends CompletionStage<U>> fn;
-        final CompletableFuture<U> dst;
-        AsyncCompose(T arg,
-                     Function<? super T, ? extends CompletionStage<U>> fn,
-                     CompletableFuture<U> dst) {
-            this.arg = arg; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<U> d, fr; U u; Throwable ex;
-            if ((d = this.dst) != null && d.result == null) {
-                try {
-                    CompletionStage<U> cs = fn.apply(arg);
-                    fr = (cs == null) ? null : cs.toCompletableFuture();
-                    ex = (fr == null) ? new NullPointerException() : null;
-                } catch (Throwable rex) {
-                    ex = rex;
-                    fr = null;
-                }
-                if (ex != null)
-                    u = null;
-                else {
-                    Object r = fr.result;
-                    if (r == null)
-                        r = fr.waitingGet(false);
-                    if (r instanceof AltResult) {
-                        ex = ((AltResult)r).ex;
-                        u = null;
-                    }
-                    else {
-                        @SuppressWarnings("unchecked") U ur = (U) r;
-                        u = ur;
-                    }
-                }
-                d.internalComplete(u, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AsyncWhenComplete<T> extends Async {
-        final T arg1;
-        final Throwable arg2;
-        final BiConsumer<? super T,? super Throwable> fn;
-        final CompletableFuture<T> dst;
-        AsyncWhenComplete(T arg1, Throwable arg2,
-                          BiConsumer<? super T,? super Throwable> fn,
-                          CompletableFuture<T> dst) {
-            this.arg1 = arg1; this.arg2 = arg2; this.fn = fn; this.dst = dst;
-        }
-        public final boolean exec() {
-            CompletableFuture<T> d;
-            if ((d = this.dst) != null && d.result == null) {
-                Throwable ex = arg2;
-                try {
-                    fn.accept(arg1, ex);
-                } catch (Throwable rex) {
-                    if (ex == null)
-                        ex = rex;
-                }
-                d.internalComplete(arg1, ex);
-            }
-            return true;
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    /* ------------- Completions -------------- */
-
-    /**
-     * Simple linked list nodes to record completions, used in
-     * basically the same way as WaitNodes. (We separate nodes from
-     * the Completions themselves mainly because for the And and Or
-     * methods, the same Completion object resides in two lists.)
+     * Returns raw result after waiting, or null if interrupted, or
+     * throws TimeoutException on timeout.
      */
-    static final class CompletionNode {
-        final Completion completion;
-        volatile CompletionNode next;
-        CompletionNode(Completion completion) { this.completion = completion; }
-    }
-
-    // Opportunistically subclass AtomicInteger to use compareAndSet to claim.
-    @SuppressWarnings("serial")
-    abstract static class Completion extends AtomicInteger implements Runnable {
-    }
-
-    static final class ThenApply<T,U> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final Function<? super T,? extends U> fn;
-        final CompletableFuture<U> dst;
-        final Executor executor;
-        ThenApply(CompletableFuture<? extends T> src,
-                  Function<? super T,? extends U> fn,
-                  CompletableFuture<U> dst,
-                  Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final Function<? super T,? extends U> fn;
-            final CompletableFuture<U> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                U u = null;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncApply<T,U>(t, fn, dst));
-                        else
-                            u = fn.apply(t);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(u, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenAccept<T> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final Consumer<? super T> fn;
-        final CompletableFuture<?> dst;
-        final Executor executor;
-        ThenAccept(CompletableFuture<? extends T> src,
-                   Consumer<? super T> fn,
-                   CompletableFuture<?> dst,
-                   Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final Consumer<? super T> fn;
-            final CompletableFuture<?> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncAccept<T>(t, fn, dst));
-                        else
-                            fn.accept(t);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenRun extends Completion {
-        final CompletableFuture<?> src;
-        final Runnable fn;
-        final CompletableFuture<Void> dst;
-        final Executor executor;
-        ThenRun(CompletableFuture<?> src,
-                Runnable fn,
-                CompletableFuture<Void> dst,
-                Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final Runnable fn;
-            final CompletableFuture<Void> dst;
-            Object r; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult)
-                    ex = ((AltResult)r).ex;
-                else
-                    ex = null;
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncRun(fn, dst));
-                        else
-                            fn.run();
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenCombine<T,U,V> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final CompletableFuture<? extends U> snd;
-        final BiFunction<? super T,? super U,? extends V> fn;
-        final CompletableFuture<V> dst;
-        final Executor executor;
-        ThenCombine(CompletableFuture<? extends T> src,
-                    CompletableFuture<? extends U> snd,
-                    BiFunction<? super T,? super U,? extends V> fn,
-                    CompletableFuture<V> dst,
-                    Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final CompletableFuture<? extends U> b;
-            final BiFunction<? super T,? super U,? extends V> fn;
-            final CompletableFuture<V> dst;
-            Object r, s; T t; U u; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                (b = this.snd) != null &&
-                (s = b.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                if (ex != null)
-                    u = null;
-                else if (s instanceof AltResult) {
-                    ex = ((AltResult)s).ex;
-                    u = null;
-                }
-                else {
-                    @SuppressWarnings("unchecked") U us = (U) s;
-                    u = us;
-                }
-                Executor e = executor;
-                V v = null;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
-                        else
-                            v = fn.apply(t, u);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(v, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenAcceptBoth<T,U> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final CompletableFuture<? extends U> snd;
-        final BiConsumer<? super T,? super U> fn;
-        final CompletableFuture<Void> dst;
-        final Executor executor;
-        ThenAcceptBoth(CompletableFuture<? extends T> src,
-                       CompletableFuture<? extends U> snd,
-                       BiConsumer<? super T,? super U> fn,
-                       CompletableFuture<Void> dst,
-                       Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final CompletableFuture<? extends U> b;
-            final BiConsumer<? super T,? super U> fn;
-            final CompletableFuture<Void> dst;
-            Object r, s; T t; U u; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                (b = this.snd) != null &&
-                (s = b.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                if (ex != null)
-                    u = null;
-                else if (s instanceof AltResult) {
-                    ex = ((AltResult)s).ex;
-                    u = null;
-                }
-                else {
-                    @SuppressWarnings("unchecked") U us = (U) s;
-                    u = us;
-                }
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
-                        else
-                            fn.accept(t, u);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class RunAfterBoth extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<?> snd;
-        final Runnable fn;
-        final CompletableFuture<Void> dst;
-        final Executor executor;
-        RunAfterBoth(CompletableFuture<?> src,
-                     CompletableFuture<?> snd,
-                     Runnable fn,
-                     CompletableFuture<Void> dst,
-                     Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<?> b;
-            final Runnable fn;
-            final CompletableFuture<Void> dst;
-            Object r, s; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                (b = this.snd) != null &&
-                (s = b.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult)
-                    ex = ((AltResult)r).ex;
-                else
-                    ex = null;
-                if (ex == null && (s instanceof AltResult))
-                    ex = ((AltResult)s).ex;
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncRun(fn, dst));
-                        else
-                            fn.run();
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AndCompletion extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<?> snd;
-        final CompletableFuture<Void> dst;
-        AndCompletion(CompletableFuture<?> src,
-                      CompletableFuture<?> snd,
-                      CompletableFuture<Void> dst) {
-            this.src = src; this.snd = snd; this.dst = dst;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<?> b;
-            final CompletableFuture<Void> dst;
-            Object r, s; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                (b = this.snd) != null &&
-                (s = b.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult)
-                    ex = ((AltResult)r).ex;
-                else
-                    ex = null;
-                if (ex == null && (s instanceof AltResult))
-                    ex = ((AltResult)s).ex;
-                dst.internalComplete(null, ex);
+    private Object timedGet(long nanos) throws TimeoutException {
+        if (Thread.interrupted())
+            return null;
+        if (nanos <= 0L)
+            throw new TimeoutException();
+        long d = System.nanoTime() + nanos;
+        Signaller q = new Signaller(true, nanos, d == 0L ? 1L : d); // avoid 0
+        boolean queued = false;
+        Object r;
+        // We intentionally don't spin here (as waitingGet does) because
+        // the call to nanoTime() above acts much like a spin.
+        while ((r = result) == null) {
+            if (!queued)
+                queued = tryPushStack(q);
+            else if (q.interruptControl < 0 || q.nanos <= 0L) {
+                q.thread = null;
+                cleanStack();
+                if (q.interruptControl < 0)
+                    return null;
+                throw new TimeoutException();
             }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ApplyToEither<T,U> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final CompletableFuture<? extends T> snd;
-        final Function<? super T,? extends U> fn;
-        final CompletableFuture<U> dst;
-        final Executor executor;
-        ApplyToEither(CompletableFuture<? extends T> src,
-                      CompletableFuture<? extends T> snd,
-                      Function<? super T,? extends U> fn,
-                      CompletableFuture<U> dst,
-                      Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final CompletableFuture<? extends T> b;
-            final Function<? super T,? extends U> fn;
-            final CompletableFuture<U> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (((a = this.src) != null && (r = a.result) != null) ||
-                 ((b = this.snd) != null && (r = b.result) != null)) &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                U u = null;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncApply<T,U>(t, fn, dst));
-                        else
-                            u = fn.apply(t);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(u, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class AcceptEither<T> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final CompletableFuture<? extends T> snd;
-        final Consumer<? super T> fn;
-        final CompletableFuture<Void> dst;
-        final Executor executor;
-        AcceptEither(CompletableFuture<? extends T> src,
-                     CompletableFuture<? extends T> snd,
-                     Consumer<? super T> fn,
-                     CompletableFuture<Void> dst,
-                     Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final CompletableFuture<? extends T> b;
-            final Consumer<? super T> fn;
-            final CompletableFuture<Void> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (((a = this.src) != null && (r = a.result) != null) ||
-                 ((b = this.snd) != null && (r = b.result) != null)) &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncAccept<T>(t, fn, dst));
-                        else
-                            fn.accept(t);
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class RunAfterEither extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<?> snd;
-        final Runnable fn;
-        final CompletableFuture<Void> dst;
-        final Executor executor;
-        RunAfterEither(CompletableFuture<?> src,
-                       CompletableFuture<?> snd,
-                       Runnable fn,
-                       CompletableFuture<Void> dst,
-                       Executor executor) {
-            this.src = src; this.snd = snd;
-            this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<?> b;
-            final Runnable fn;
-            final CompletableFuture<Void> dst;
-            Object r; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (((a = this.src) != null && (r = a.result) != null) ||
-                 ((b = this.snd) != null && (r = b.result) != null)) &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult)
-                    ex = ((AltResult)r).ex;
-                else
-                    ex = null;
-                Executor e = executor;
-                if (ex == null) {
-                    try {
-                        if (e != null)
-                            execAsync(e, new AsyncRun(fn, dst));
-                        else
-                            fn.run();
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-                if (e == null || ex != null)
-                    dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class OrCompletion extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<?> snd;
-        final CompletableFuture<Object> dst;
-        OrCompletion(CompletableFuture<?> src,
-                     CompletableFuture<?> snd,
-                     CompletableFuture<Object> dst) {
-            this.src = src; this.snd = snd; this.dst = dst;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<?> b;
-            final CompletableFuture<Object> dst;
-            Object r, t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (((a = this.src) != null && (r = a.result) != null) ||
-                 ((b = this.snd) != null && (r = b.result) != null)) &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    t = r;
-                }
-                dst.internalComplete(t, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ExceptionCompletion<T> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final Function<? super Throwable, ? extends T> fn;
-        final CompletableFuture<T> dst;
-        ExceptionCompletion(CompletableFuture<? extends T> src,
-                            Function<? super Throwable, ? extends T> fn,
-                            CompletableFuture<T> dst) {
-            this.src = src; this.fn = fn; this.dst = dst;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final Function<? super Throwable, ? extends T> fn;
-            final CompletableFuture<T> dst;
-            Object r; T t = null; Throwable ex, dx = null;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if ((r instanceof AltResult) &&
-                    (ex = ((AltResult)r).ex) != null) {
-                    try {
-                        t = fn.apply(ex);
-                    } catch (Throwable rex) {
-                        dx = rex;
-                    }
-                }
-                else {
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                dst.internalComplete(t, dx);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class WhenCompleteCompletion<T> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final BiConsumer<? super T, ? super Throwable> fn;
-        final CompletableFuture<T> dst;
-        final Executor executor;
-        WhenCompleteCompletion(CompletableFuture<? extends T> src,
-                                  BiConsumer<? super T, ? super Throwable> fn,
-                                  CompletableFuture<T> dst,
-                                  Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final BiConsumer<? super T, ? super Throwable> fn;
-            final CompletableFuture<T> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                Throwable dx = null;
+            else if (q.thread != null && result == null) {
                 try {
-                    if (e != null)
-                        execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
-                    else
-                        fn.accept(t, ex);
-                } catch (Throwable rex) {
-                    dx = rex;
-                }
-                if (e == null || dx != null)
-                    dst.internalComplete(t, ex != null ? ex : dx);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenCopy<T> extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<T> dst;
-        ThenCopy(CompletableFuture<?> src,
-                 CompletableFuture<T> dst) {
-            this.src = src; this.dst = dst;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<T> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                dst.internalComplete(t, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    // version of ThenCopy for CompletableFuture<Void> dst
-    static final class ThenPropagate extends Completion {
-        final CompletableFuture<?> src;
-        final CompletableFuture<Void> dst;
-        ThenPropagate(CompletableFuture<?> src,
-                      CompletableFuture<Void> dst) {
-            this.src = src; this.dst = dst;
-        }
-        public final void run() {
-            final CompletableFuture<?> a;
-            final CompletableFuture<Void> dst;
-            Object r; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult)
-                    ex = ((AltResult)r).ex;
-                else
-                    ex = null;
-                dst.internalComplete(null, ex);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class HandleCompletion<T,U> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final BiFunction<? super T, Throwable, ? extends U> fn;
-        final CompletableFuture<U> dst;
-        final Executor executor;
-        HandleCompletion(CompletableFuture<? extends T> src,
-                         BiFunction<? super T, Throwable, ? extends U> fn,
-                         CompletableFuture<U> dst,
-                          Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final BiFunction<? super T, Throwable, ? extends U> fn;
-            final CompletableFuture<U> dst;
-            Object r; T t; Throwable ex;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                Executor e = executor;
-                U u = null;
-                Throwable dx = null;
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
-                    else
-                        u = fn.apply(t, ex);
-                } catch (Throwable rex) {
-                    dx = rex;
-                }
-                if (e == null || dx != null)
-                    dst.internalComplete(u, dx);
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    static final class ThenCompose<T,U> extends Completion {
-        final CompletableFuture<? extends T> src;
-        final Function<? super T, ? extends CompletionStage<U>> fn;
-        final CompletableFuture<U> dst;
-        final Executor executor;
-        ThenCompose(CompletableFuture<? extends T> src,
-                    Function<? super T, ? extends CompletionStage<U>> fn,
-                    CompletableFuture<U> dst,
-                    Executor executor) {
-            this.src = src; this.fn = fn; this.dst = dst;
-            this.executor = executor;
-        }
-        public final void run() {
-            final CompletableFuture<? extends T> a;
-            final Function<? super T, ? extends CompletionStage<U>> fn;
-            final CompletableFuture<U> dst;
-            Object r; T t; Throwable ex; Executor e;
-            if ((dst = this.dst) != null &&
-                (fn = this.fn) != null &&
-                (a = this.src) != null &&
-                (r = a.result) != null &&
-                compareAndSet(0, 1)) {
-                if (r instanceof AltResult) {
-                    ex = ((AltResult)r).ex;
-                    t = null;
-                }
-                else {
-                    ex = null;
-                    @SuppressWarnings("unchecked") T tr = (T) r;
-                    t = tr;
-                }
-                CompletableFuture<U> c = null;
-                U u = null;
-                boolean complete = false;
-                if (ex == null) {
-                    if ((e = executor) != null)
-                        execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
-                    else {
-                        try {
-                            CompletionStage<U> cs = fn.apply(t);
-                            c = (cs == null) ? null : cs.toCompletableFuture();
-                            if (c == null)
-                                ex = new NullPointerException();
-                        } catch (Throwable rex) {
-                            ex = rex;
-                        }
-                    }
-                }
-                if (c != null) {
-                    ThenCopy<U> d = null;
-                    Object s;
-                    if ((s = c.result) == null) {
-                        CompletionNode p = new CompletionNode
-                            (d = new ThenCopy<U>(c, dst));
-                        while ((s = c.result) == null) {
-                            if (UNSAFE.compareAndSwapObject
-                                (c, COMPLETIONS, p.next = c.completions, p))
-                                break;
-                        }
-                    }
-                    if (s != null && (d == null || d.compareAndSet(0, 1))) {
-                        complete = true;
-                        if (s instanceof AltResult) {
-                            ex = ((AltResult)s).ex;  // no rewrap
-                            u = null;
-                        }
-                        else {
-                            @SuppressWarnings("unchecked") U us = (U) s;
-                            u = us;
-                        }
-                    }
-                }
-                if (complete || ex != null)
-                    dst.internalComplete(u, ex);
-                if (c != null)
-                    c.helpPostComplete();
-            }
-        }
-        private static final long serialVersionUID = 5232453952276885070L;
-    }
-
-    // Implementations of stage methods with (plain, async, Executor) forms
-
-    private <U> CompletableFuture<U> doThenApply
-        (Function<? super T,? extends U> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        ThenApply<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenApply<T,U>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncApply<T,U>(t, fn, dst));
-                    else
-                        u = fn.apply(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(u, ex);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-    private CompletableFuture<Void> doThenAccept(Consumer<? super T> fn,
-                                                 Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenAccept<T> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenAccept<T>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncAccept<T>(t, fn, dst));
-                    else
-                        fn.accept(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-    private CompletableFuture<Void> doThenRun(Runnable action,
-                                              Executor e) {
-        if (action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenRun d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p = new CompletionNode
-                (d = new ThenRun(this, action, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-    private <U,V> CompletableFuture<V> doThenCombine
-        (CompletableFuture<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<V> dst = new CompletableFuture<V>();
-        ThenCombine<T,U,V> d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new ThenCombine<T,U,V>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
+                    ForkJoinPool.managedBlock(q);
+                } catch (InterruptedException ie) {
+                    q.interruptControl = -1;
                 }
             }
         }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; U u; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex != null)
-                u = null;
-            else if (s instanceof AltResult) {
-                ex = ((AltResult)s).ex;
-                u = null;
-            }
-            else {
-                @SuppressWarnings("unchecked") U us = (U) s;
-                u = us;
-            }
-            V v = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncCombine<T,U,V>(t, u, fn, dst));
-                    else
-                        v = fn.apply(t, u);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(v, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    private <U> CompletableFuture<Void> doThenAcceptBoth
-        (CompletableFuture<? extends U> other,
-         BiConsumer<? super T,? super U> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        ThenAcceptBoth<T,U> d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
-                }
-            }
-        }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; U u; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex != null)
-                u = null;
-            else if (s instanceof AltResult) {
-                ex = ((AltResult)s).ex;
-                u = null;
-            }
-            else {
-                @SuppressWarnings("unchecked") U us = (U) s;
-                u = us;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncAcceptBoth<T,U>(t, u, fn, dst));
-                    else
-                        fn.accept(t, u);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    private CompletableFuture<Void> doRunAfterBoth(CompletableFuture<?> other,
-                                                   Runnable action,
-                                                   Executor e) {
-        if (other == null || action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        RunAfterBoth d = null;
-        Object r, s = null;
-        if ((r = result) == null || (s = other.result) == null) {
-            d = new RunAfterBoth(this, other, action, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r == null && (r = result) == null) ||
-                   (s == null && (s = other.result) == null)) {
-                if (q != null) {
-                    if (s != null ||
-                        UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (r != null ||
-                         UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p)) {
-                    if (s != null)
-                        break;
-                    q = new CompletionNode(d);
-                }
-            }
-        }
-        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null && (s instanceof AltResult))
-                ex = ((AltResult)s).ex;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    private <U> CompletableFuture<U> doApplyToEither
-        (CompletableFuture<? extends T> other,
-         Function<? super T, U> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        ApplyToEither<T,U> d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new ApplyToEither<T,U>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncApply<T,U>(t, fn, dst));
-                    else
-                        u = fn.apply(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(u, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
+        if (q.interruptControl < 0)
+            r = null;
+        q.thread = null;
+        postComplete();
+        return r;
     }
 
-    private CompletableFuture<Void> doAcceptEither
-        (CompletableFuture<? extends T> other,
-         Consumer<? super T> fn,
-         Executor e) {
-        if (other == null || fn == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        AcceptEither<T> d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new AcceptEither<T>(this, other, fn, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncAccept<T>(t, fn, dst));
-                    else
-                        fn.accept(t);
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    private CompletableFuture<Void> doRunAfterEither
-        (CompletableFuture<?> other,
-         Runnable action,
-         Executor e) {
-        if (other == null || action == null) throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        RunAfterEither d = null;
-        Object r;
-        if ((r = result) == null && (r = other.result) == null) {
-            d = new RunAfterEither(this, other, action, dst, e);
-            CompletionNode q = null, p = new CompletionNode(d);
-            while ((r = result) == null && (r = other.result) == null) {
-                if (q != null) {
-                    if (UNSAFE.compareAndSwapObject
-                        (other, COMPLETIONS, q.next = other.completions, q))
-                        break;
-                }
-                else if (UNSAFE.compareAndSwapObject
-                         (this, COMPLETIONS, p.next = completions, p))
-                    q = new CompletionNode(d);
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null) {
-                try {
-                    if (e != null)
-                        execAsync(e, new AsyncRun(action, dst));
-                    else
-                        action.run();
-                } catch (Throwable rex) {
-                    ex = rex;
-                }
-            }
-            if (e == null || ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        other.helpPostComplete();
-        return dst;
-    }
-
-    private <U> CompletableFuture<U> doThenCompose
-        (Function<? super T, ? extends CompletionStage<U>> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = null;
-        ThenCompose<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            dst = new CompletableFuture<U>();
-            CompletionNode p = new CompletionNode
-                (d = new ThenCompose<T,U>(this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (this, COMPLETIONS, p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            if (ex == null) {
-                if (e != null) {
-                    if (dst == null)
-                        dst = new CompletableFuture<U>();
-                    execAsync(e, new AsyncCompose<T,U>(t, fn, dst));
-                }
-                else {
-                    try {
-                        CompletionStage<U> cs = fn.apply(t);
-                        if (cs == null ||
-                            (dst = cs.toCompletableFuture()) == null)
-                            ex = new NullPointerException();
-                    } catch (Throwable rex) {
-                        ex = rex;
-                    }
-                }
-            }
-            if (dst == null)
-                dst = new CompletableFuture<U>();
-            if (ex != null)
-                dst.internalComplete(null, ex);
-        }
-        helpPostComplete();
-        dst.helpPostComplete();
-        return dst;
-    }
-
-    private CompletableFuture<T> doWhenComplete
-        (BiConsumer<? super T, ? super Throwable> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<T> dst = new CompletableFuture<T>();
-        WhenCompleteCompletion<T> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p =
-                new CompletionNode(d = new WhenCompleteCompletion<T>
-                                   (this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
-                                                p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            Throwable dx = null;
-            try {
-                if (e != null)
-                    execAsync(e, new AsyncWhenComplete<T>(t, ex, fn, dst));
-                else
-                    fn.accept(t, ex);
-            } catch (Throwable rex) {
-                dx = rex;
-            }
-            if (e == null || dx != null)
-                dst.internalComplete(t, ex != null ? ex : dx);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-    private <U> CompletableFuture<U> doHandle
-        (BiFunction<? super T, Throwable, ? extends U> fn,
-         Executor e) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<U> dst = new CompletableFuture<U>();
-        HandleCompletion<T,U> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p =
-                new CompletionNode(d = new HandleCompletion<T,U>
-                                   (this, fn, dst, e));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
-                                                p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t; Throwable ex;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            U u = null;
-            Throwable dx = null;
-            try {
-                if (e != null)
-                    execAsync(e, new AsyncCombine<T,Throwable,U>(t, ex, fn, dst));
-                else {
-                    u = fn.apply(t, ex);
-                    dx = null;
-                }
-            } catch (Throwable rex) {
-                dx = rex;
-                u = null;
-            }
-            if (e == null || dx != null)
-                dst.internalComplete(u, dx);
-        }
-        helpPostComplete();
-        return dst;
-    }
-
-
-    // public methods
+    /* ------------- public methods -------------- */
 
     /**
      * Creates a new incomplete CompletableFuture.
@@ -2114,6 +1786,13 @@
     }
 
     /**
+     * Creates a new complete CompletableFuture with given encoded result.
+     */
+    private CompletableFuture(Object r) {
+        this.result = r;
+    }
+
+    /**
      * Returns a new CompletableFuture that is asynchronously completed
      * by a task running in the {@link ForkJoinPool#commonPool()} with
      * the value obtained by calling the given Supplier.
@@ -2124,10 +1803,7 @@
      * @return the new CompletableFuture
      */
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
-        if (supplier == null) throw new NullPointerException();
-        CompletableFuture<U> f = new CompletableFuture<U>();
-        execAsync(ForkJoinPool.commonPool(), new AsyncSupply<U>(supplier, f));
-        return f;
+        return asyncSupplyStage(asyncPool, supplier);
     }
 
     /**
@@ -2143,11 +1819,7 @@
      */
     public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                        Executor executor) {
-        if (executor == null || supplier == null)
-            throw new NullPointerException();
-        CompletableFuture<U> f = new CompletableFuture<U>();
-        execAsync(executor, new AsyncSupply<U>(supplier, f));
-        return f;
+        return asyncSupplyStage(screenExecutor(executor), supplier);
     }
 
     /**
@@ -2160,10 +1832,7 @@
      * @return the new CompletableFuture
      */
     public static CompletableFuture<Void> runAsync(Runnable runnable) {
-        if (runnable == null) throw new NullPointerException();
-        CompletableFuture<Void> f = new CompletableFuture<Void>();
-        execAsync(ForkJoinPool.commonPool(), new AsyncRun(runnable, f));
-        return f;
+        return asyncRunStage(asyncPool, runnable);
     }
 
     /**
@@ -2178,11 +1847,7 @@
      */
     public static CompletableFuture<Void> runAsync(Runnable runnable,
                                                    Executor executor) {
-        if (executor == null || runnable == null)
-            throw new NullPointerException();
-        CompletableFuture<Void> f = new CompletableFuture<Void>();
-        execAsync(executor, new AsyncRun(runnable, f));
-        return f;
+        return asyncRunStage(screenExecutor(executor), runnable);
     }
 
     /**
@@ -2194,9 +1859,7 @@
      * @return the completed CompletableFuture
      */
     public static <U> CompletableFuture<U> completedFuture(U value) {
-        CompletableFuture<U> f = new CompletableFuture<U>();
-        f.result = (value == null) ? NIL : value;
-        return f;
+        return new CompletableFuture<U>((value == null) ? NIL : value);
     }
 
     /**
@@ -2220,21 +1883,8 @@
      * while waiting
      */
     public T get() throws InterruptedException, ExecutionException {
-        Object r; Throwable ex, cause;
-        if ((r = result) == null && (r = waitingGet(true)) == null)
-            throw new InterruptedException();
-        if (!(r instanceof AltResult)) {
-            @SuppressWarnings("unchecked") T tr = (T) r;
-            return tr;
-        }
-        if ((ex = ((AltResult)r).ex) == null)
-            return null;
-        if (ex instanceof CancellationException)
-            throw (CancellationException)ex;
-        if ((ex instanceof CompletionException) &&
-            (cause = ex.getCause()) != null)
-            ex = cause;
-        throw new ExecutionException(ex);
+        Object r;
+        return reportGet((r = result) == null ? waitingGet(true) : r);
     }
 
     /**
@@ -2252,24 +1902,9 @@
      */
     public T get(long timeout, TimeUnit unit)
         throws InterruptedException, ExecutionException, TimeoutException {
-        Object r; Throwable ex, cause;
+        Object r;
         long nanos = unit.toNanos(timeout);
-        if (Thread.interrupted())
-            throw new InterruptedException();
-        if ((r = result) == null)
-            r = timedAwaitDone(nanos);
-        if (!(r instanceof AltResult)) {
-            @SuppressWarnings("unchecked") T tr = (T) r;
-            return tr;
-        }
-        if ((ex = ((AltResult)r).ex) == null)
-            return null;
-        if (ex instanceof CancellationException)
-            throw (CancellationException)ex;
-        if ((ex instanceof CompletionException) &&
-            (cause = ex.getCause()) != null)
-            ex = cause;
-        throw new ExecutionException(ex);
+        return reportGet((r = result) == null ? timedGet(nanos) : r);
     }
 
     /**
@@ -2287,20 +1922,8 @@
      * exceptionally or a completion computation threw an exception
      */
     public T join() {
-        Object r; Throwable ex;
-        if ((r = result) == null)
-            r = waitingGet(false);
-        if (!(r instanceof AltResult)) {
-            @SuppressWarnings("unchecked") T tr = (T) r;
-            return tr;
-        }
-        if ((ex = ((AltResult)r).ex) == null)
-            return null;
-        if (ex instanceof CancellationException)
-            throw (CancellationException)ex;
-        if (ex instanceof CompletionException)
-            throw (CompletionException)ex;
-        throw new CompletionException(ex);
+        Object r;
+        return reportJoin((r = result) == null ? waitingGet(false) : r);
     }
 
     /**
@@ -2314,20 +1937,8 @@
      * exceptionally or a completion computation threw an exception
      */
     public T getNow(T valueIfAbsent) {
-        Object r; Throwable ex;
-        if ((r = result) == null)
-            return valueIfAbsent;
-        if (!(r instanceof AltResult)) {
-            @SuppressWarnings("unchecked") T tr = (T) r;
-            return tr;
-        }
-        if ((ex = ((AltResult)r).ex) == null)
-            return null;
-        if (ex instanceof CancellationException)
-            throw (CancellationException)ex;
-        if (ex instanceof CompletionException)
-            throw (CompletionException)ex;
-        throw new CompletionException(ex);
+        Object r;
+        return ((r = result) == null) ? valueIfAbsent : reportJoin(r);
     }
 
     /**
@@ -2339,9 +1950,7 @@
      * to transition to a completed state, else {@code false}
      */
     public boolean complete(T value) {
-        boolean triggered = result == null &&
-            UNSAFE.compareAndSwapObject(this, RESULT, null,
-                                        value == null ? NIL : value);
+        boolean triggered = completeValue(value);
         postComplete();
         return triggered;
     }
@@ -2356,244 +1965,200 @@
      */
     public boolean completeExceptionally(Throwable ex) {
         if (ex == null) throw new NullPointerException();
-        boolean triggered = result == null &&
-            UNSAFE.compareAndSwapObject(this, RESULT, null, new AltResult(ex));
+        boolean triggered = internalComplete(new AltResult(ex));
         postComplete();
         return triggered;
     }
 
-    // CompletionStage methods
-
-    public <U> CompletableFuture<U> thenApply
-        (Function<? super T,? extends U> fn) {
-        return doThenApply(fn, null);
+    public <U> CompletableFuture<U> thenApply(
+        Function<? super T,? extends U> fn) {
+        return uniApplyStage(null, fn);
     }
 
-    public <U> CompletableFuture<U> thenApplyAsync
-        (Function<? super T,? extends U> fn) {
-        return doThenApply(fn, ForkJoinPool.commonPool());
+    public <U> CompletableFuture<U> thenApplyAsync(
+        Function<? super T,? extends U> fn) {
+        return uniApplyStage(asyncPool, fn);
     }
 
-    public <U> CompletableFuture<U> thenApplyAsync
-        (Function<? super T,? extends U> fn,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenApply(fn, executor);
+    public <U> CompletableFuture<U> thenApplyAsync(
+        Function<? super T,? extends U> fn, Executor executor) {
+        return uniApplyStage(screenExecutor(executor), fn);
     }
 
-    public CompletableFuture<Void> thenAccept
-        (Consumer<? super T> action) {
-        return doThenAccept(action, null);
+    public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
+        return uniAcceptStage(null, action);
     }
 
-    public CompletableFuture<Void> thenAcceptAsync
-        (Consumer<? super T> action) {
-        return doThenAccept(action, ForkJoinPool.commonPool());
+    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action) {
+        return uniAcceptStage(asyncPool, action);
     }
 
-    public CompletableFuture<Void> thenAcceptAsync
-        (Consumer<? super T> action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenAccept(action, executor);
+    public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,
+                                                   Executor executor) {
+        return uniAcceptStage(screenExecutor(executor), action);
     }
 
-    public CompletableFuture<Void> thenRun
-        (Runnable action) {
-        return doThenRun(action, null);
+    public CompletableFuture<Void> thenRun(Runnable action) {
+        return uniRunStage(null, action);
     }
 
-    public CompletableFuture<Void> thenRunAsync
-        (Runnable action) {
-        return doThenRun(action, ForkJoinPool.commonPool());
+    public CompletableFuture<Void> thenRunAsync(Runnable action) {
+        return uniRunStage(asyncPool, action);
     }
 
-    public CompletableFuture<Void> thenRunAsync
-        (Runnable action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenRun(action, executor);
+    public CompletableFuture<Void> thenRunAsync(Runnable action,
+                                                Executor executor) {
+        return uniRunStage(screenExecutor(executor), action);
     }
 
-    public <U,V> CompletableFuture<V> thenCombine
-        (CompletionStage<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn) {
-        return doThenCombine(other.toCompletableFuture(), fn, null);
+    public <U,V> CompletableFuture<V> thenCombine(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn) {
+        return biApplyStage(null, other, fn);
     }
 
-    public <U,V> CompletableFuture<V> thenCombineAsync
-        (CompletionStage<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn) {
-        return doThenCombine(other.toCompletableFuture(), fn,
-                             ForkJoinPool.commonPool());
+    public <U,V> CompletableFuture<V> thenCombineAsync(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn) {
+        return biApplyStage(asyncPool, other, fn);
     }
 
-    public <U,V> CompletableFuture<V> thenCombineAsync
-        (CompletionStage<? extends U> other,
-         BiFunction<? super T,? super U,? extends V> fn,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenCombine(other.toCompletableFuture(), fn, executor);
+    public <U,V> CompletableFuture<V> thenCombineAsync(
+        CompletionStage<? extends U> other,
+        BiFunction<? super T,? super U,? extends V> fn, Executor executor) {
+        return biApplyStage(screenExecutor(executor), other, fn);
     }
 
-    public <U> CompletableFuture<Void> thenAcceptBoth
-        (CompletionStage<? extends U> other,
-         BiConsumer<? super T, ? super U> action) {
-        return doThenAcceptBoth(other.toCompletableFuture(), action, null);
+    public <U> CompletableFuture<Void> thenAcceptBoth(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action) {
+        return biAcceptStage(null, other, action);
     }
 
-    public <U> CompletableFuture<Void> thenAcceptBothAsync
-        (CompletionStage<? extends U> other,
-         BiConsumer<? super T, ? super U> action) {
-        return doThenAcceptBoth(other.toCompletableFuture(), action,
-                                ForkJoinPool.commonPool());
+    public <U> CompletableFuture<Void> thenAcceptBothAsync(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action) {
+        return biAcceptStage(asyncPool, other, action);
     }
 
-    public <U> CompletableFuture<Void> thenAcceptBothAsync
-        (CompletionStage<? extends U> other,
-         BiConsumer<? super T, ? super U> action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenAcceptBoth(other.toCompletableFuture(), action, executor);
-    }
-
-    public CompletableFuture<Void> runAfterBoth
-        (CompletionStage<?> other,
-         Runnable action) {
-        return doRunAfterBoth(other.toCompletableFuture(), action, null);
+    public <U> CompletableFuture<Void> thenAcceptBothAsync(
+        CompletionStage<? extends U> other,
+        BiConsumer<? super T, ? super U> action, Executor executor) {
+        return biAcceptStage(screenExecutor(executor), other, action);
     }
 
-    public CompletableFuture<Void> runAfterBothAsync
-        (CompletionStage<?> other,
-         Runnable action) {
-        return doRunAfterBoth(other.toCompletableFuture(), action,
-                              ForkJoinPool.commonPool());
+    public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other,
+                                                Runnable action) {
+        return biRunStage(null, other, action);
     }
 
-    public CompletableFuture<Void> runAfterBothAsync
-        (CompletionStage<?> other,
-         Runnable action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doRunAfterBoth(other.toCompletableFuture(), action, executor);
+    public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                     Runnable action) {
+        return biRunStage(asyncPool, other, action);
     }
 
-
-    public <U> CompletableFuture<U> applyToEither
-        (CompletionStage<? extends T> other,
-         Function<? super T, U> fn) {
-        return doApplyToEither(other.toCompletableFuture(), fn, null);
+    public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other,
+                                                     Runnable action,
+                                                     Executor executor) {
+        return biRunStage(screenExecutor(executor), other, action);
     }
 
-    public <U> CompletableFuture<U> applyToEitherAsync
-        (CompletionStage<? extends T> other,
-         Function<? super T, U> fn) {
-        return doApplyToEither(other.toCompletableFuture(), fn,
-                               ForkJoinPool.commonPool());
+    public <U> CompletableFuture<U> applyToEither(
+        CompletionStage<? extends T> other, Function<? super T, U> fn) {
+        return orApplyStage(null, other, fn);
+    }
+
+    public <U> CompletableFuture<U> applyToEitherAsync(
+        CompletionStage<? extends T> other, Function<? super T, U> fn) {
+        return orApplyStage(asyncPool, other, fn);
     }
 
-    public <U> CompletableFuture<U> applyToEitherAsync
-        (CompletionStage<? extends T> other,
-         Function<? super T, U> fn,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doApplyToEither(other.toCompletableFuture(), fn, executor);
-    }
-
-    public CompletableFuture<Void> acceptEither
-        (CompletionStage<? extends T> other,
-         Consumer<? super T> action) {
-        return doAcceptEither(other.toCompletableFuture(), action, null);
+    public <U> CompletableFuture<U> applyToEitherAsync(
+        CompletionStage<? extends T> other, Function<? super T, U> fn,
+        Executor executor) {
+        return orApplyStage(screenExecutor(executor), other, fn);
     }
 
-    public CompletableFuture<Void> acceptEitherAsync
-        (CompletionStage<? extends T> other,
-         Consumer<? super T> action) {
-        return doAcceptEither(other.toCompletableFuture(), action,
-                              ForkJoinPool.commonPool());
+    public CompletableFuture<Void> acceptEither(
+        CompletionStage<? extends T> other, Consumer<? super T> action) {
+        return orAcceptStage(null, other, action);
     }
 
-    public CompletableFuture<Void> acceptEitherAsync
-        (CompletionStage<? extends T> other,
-         Consumer<? super T> action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doAcceptEither(other.toCompletableFuture(), action, executor);
+    public CompletableFuture<Void> acceptEitherAsync(
+        CompletionStage<? extends T> other, Consumer<? super T> action) {
+        return orAcceptStage(asyncPool, other, action);
+    }
+
+    public CompletableFuture<Void> acceptEitherAsync(
+        CompletionStage<? extends T> other, Consumer<? super T> action,
+        Executor executor) {
+        return orAcceptStage(screenExecutor(executor), other, action);
     }
 
     public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,
                                                   Runnable action) {
-        return doRunAfterEither(other.toCompletableFuture(), action, null);
+        return orRunStage(null, other, action);
     }
 
-    public CompletableFuture<Void> runAfterEitherAsync
-        (CompletionStage<?> other,
-         Runnable action) {
-        return doRunAfterEither(other.toCompletableFuture(), action,
-                                ForkJoinPool.commonPool());
+    public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
+                                                       Runnable action) {
+        return orRunStage(asyncPool, other, action);
     }
 
-    public CompletableFuture<Void> runAfterEitherAsync
-        (CompletionStage<?> other,
-         Runnable action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doRunAfterEither(other.toCompletableFuture(), action, executor);
+    public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,
+                                                       Runnable action,
+                                                       Executor executor) {
+        return orRunStage(screenExecutor(executor), other, action);
     }
 
-    public <U> CompletableFuture<U> thenCompose
-        (Function<? super T, ? extends CompletionStage<U>> fn) {
-        return doThenCompose(fn, null);
+    public <U> CompletableFuture<U> thenCompose(
+        Function<? super T, ? extends CompletionStage<U>> fn) {
+        return uniComposeStage(null, fn);
     }
 
-    public <U> CompletableFuture<U> thenComposeAsync
-        (Function<? super T, ? extends CompletionStage<U>> fn) {
-        return doThenCompose(fn, ForkJoinPool.commonPool());
+    public <U> CompletableFuture<U> thenComposeAsync(
+        Function<? super T, ? extends CompletionStage<U>> fn) {
+        return uniComposeStage(asyncPool, fn);
     }
 
-    public <U> CompletableFuture<U> thenComposeAsync
-        (Function<? super T, ? extends CompletionStage<U>> fn,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doThenCompose(fn, executor);
+    public <U> CompletableFuture<U> thenComposeAsync(
+        Function<? super T, ? extends CompletionStage<U>> fn,
+        Executor executor) {
+        return uniComposeStage(screenExecutor(executor), fn);
     }
 
-    public CompletableFuture<T> whenComplete
-        (BiConsumer<? super T, ? super Throwable> action) {
-        return doWhenComplete(action, null);
+    public CompletableFuture<T> whenComplete(
+        BiConsumer<? super T, ? super Throwable> action) {
+        return uniWhenCompleteStage(null, action);
     }
 
-    public CompletableFuture<T> whenCompleteAsync
-        (BiConsumer<? super T, ? super Throwable> action) {
-        return doWhenComplete(action, ForkJoinPool.commonPool());
+    public CompletableFuture<T> whenCompleteAsync(
+        BiConsumer<? super T, ? super Throwable> action) {
+        return uniWhenCompleteStage(asyncPool, action);
     }
 
-    public CompletableFuture<T> whenCompleteAsync
-        (BiConsumer<? super T, ? super Throwable> action,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doWhenComplete(action, executor);
+    public CompletableFuture<T> whenCompleteAsync(
+        BiConsumer<? super T, ? super Throwable> action, Executor executor) {
+        return uniWhenCompleteStage(screenExecutor(executor), action);
     }
 
-    public <U> CompletableFuture<U> handle
-        (BiFunction<? super T, Throwable, ? extends U> fn) {
-        return doHandle(fn, null);
+    public <U> CompletableFuture<U> handle(
+        BiFunction<? super T, Throwable, ? extends U> fn) {
+        return uniHandleStage(null, fn);
     }
 
-    public <U> CompletableFuture<U> handleAsync
-        (BiFunction<? super T, Throwable, ? extends U> fn) {
-        return doHandle(fn, ForkJoinPool.commonPool());
+    public <U> CompletableFuture<U> handleAsync(
+        BiFunction<? super T, Throwable, ? extends U> fn) {
+        return uniHandleStage(asyncPool, fn);
     }
 
-    public <U> CompletableFuture<U> handleAsync
-        (BiFunction<? super T, Throwable, ? extends U> fn,
-         Executor executor) {
-        if (executor == null) throw new NullPointerException();
-        return doHandle(fn, executor);
+    public <U> CompletableFuture<U> handleAsync(
+        BiFunction<? super T, Throwable, ? extends U> fn, Executor executor) {
+        return uniHandleStage(screenExecutor(executor), fn);
     }
 
     /**
-     * Returns this CompletableFuture
+     * Returns this CompletableFuture.
      *
      * @return this CompletableFuture
      */
@@ -2618,52 +2183,13 @@
      * exceptionally
      * @return the new CompletableFuture
      */
-    public CompletableFuture<T> exceptionally
-        (Function<Throwable, ? extends T> fn) {
-        if (fn == null) throw new NullPointerException();
-        CompletableFuture<T> dst = new CompletableFuture<T>();
-        ExceptionCompletion<T> d = null;
-        Object r;
-        if ((r = result) == null) {
-            CompletionNode p =
-                new CompletionNode(d = new ExceptionCompletion<T>
-                                   (this, fn, dst));
-            while ((r = result) == null) {
-                if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
-                                                p.next = completions, p))
-                    break;
-            }
-        }
-        if (r != null && (d == null || d.compareAndSet(0, 1))) {
-            T t = null; Throwable ex, dx = null;
-            if (r instanceof AltResult) {
-                if ((ex = ((AltResult)r).ex) != null) {
-                    try {
-                        t = fn.apply(ex);
-                    } catch (Throwable rex) {
-                        dx = rex;
-                    }
-                }
-            }
-            else {
-                @SuppressWarnings("unchecked") T tr = (T) r;
-                t = tr;
-            }
-            dst.internalComplete(t, dx);
-        }
-        helpPostComplete();
-        return dst;
+    public CompletableFuture<T> exceptionally(
+        Function<Throwable, ? extends T> fn) {
+        return uniExceptionallyStage(fn);
     }
 
     /* ------------- Arbitrary-arity constructions -------------- */
 
-    /*
-     * The basic plan of attack is to recursively form binary
-     * completion trees of elements. This can be overkill for small
-     * sets, but scales nicely. The And/All vs Or/Any forms use the
-     * same idea, but details differ.
-     */
-
     /**
      * Returns a new CompletableFuture that is completed when all of
      * the given CompletableFutures complete.  If any of the given
@@ -2688,82 +2214,7 @@
      * {@code null}
      */
     public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {
-        int len = cfs.length; // Directly handle empty and singleton cases
-        if (len > 1)
-            return allTree(cfs, 0, len - 1);
-        else {
-            CompletableFuture<Void> dst = new CompletableFuture<Void>();
-            CompletableFuture<?> f;
-            if (len == 0)
-                dst.result = NIL;
-            else if ((f = cfs[0]) == null)
-                throw new NullPointerException();
-            else {
-                ThenPropagate d = null;
-                CompletionNode p = null;
-                Object r;
-                while ((r = f.result) == null) {
-                    if (d == null)
-                        d = new ThenPropagate(f, dst);
-                    else if (p == null)
-                        p = new CompletionNode(d);
-                    else if (UNSAFE.compareAndSwapObject
-                             (f, COMPLETIONS, p.next = f.completions, p))
-                        break;
-                }
-                if (r != null && (d == null || d.compareAndSet(0, 1)))
-                    dst.internalComplete(null, (r instanceof AltResult) ?
-                                         ((AltResult)r).ex : null);
-                f.helpPostComplete();
-            }
-            return dst;
-        }
-    }
-
-    /**
-     * Recursively constructs an And'ed tree of CompletableFutures.
-     * Called only when array known to have at least two elements.
-     */
-    private static CompletableFuture<Void> allTree(CompletableFuture<?>[] cfs,
-                                                   int lo, int hi) {
-        CompletableFuture<?> fst, snd;
-        int mid = (lo + hi) >>> 1;
-        if ((fst = (lo == mid   ? cfs[lo] : allTree(cfs, lo,    mid))) == null ||
-            (snd = (hi == mid+1 ? cfs[hi] : allTree(cfs, mid+1, hi))) == null)
-            throw new NullPointerException();
-        CompletableFuture<Void> dst = new CompletableFuture<Void>();
-        AndCompletion d = null;
-        CompletionNode p = null, q = null;
-        Object r = null, s = null;
-        while ((r = fst.result) == null || (s = snd.result) == null) {
-            if (d == null)
-                d = new AndCompletion(fst, snd, dst);
-            else if (p == null)
-                p = new CompletionNode(d);
-            else if (q == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (fst, COMPLETIONS, p.next = fst.completions, p))
-                    q = new CompletionNode(d);
-            }
-            else if (UNSAFE.compareAndSwapObject
-                     (snd, COMPLETIONS, q.next = snd.completions, q))
-                break;
-        }
-        if ((r != null || (r = fst.result) != null) &&
-            (s != null || (s = snd.result) != null) &&
-            (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex;
-            if (r instanceof AltResult)
-                ex = ((AltResult)r).ex;
-            else
-                ex = null;
-            if (ex == null && (s instanceof AltResult))
-                ex = ((AltResult)s).ex;
-            dst.internalComplete(null, ex);
-        }
-        fst.helpPostComplete();
-        snd.helpPostComplete();
-        return dst;
+        return andTree(cfs, 0, cfs.length - 1);
     }
 
     /**
@@ -2782,92 +2233,7 @@
      * {@code null}
      */
     public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {
-        int len = cfs.length; // Same idea as allOf
-        if (len > 1)
-            return anyTree(cfs, 0, len - 1);
-        else {
-            CompletableFuture<Object> dst = new CompletableFuture<Object>();
-            CompletableFuture<?> f;
-            if (len == 0)
-                ; // skip
-            else if ((f = cfs[0]) == null)
-                throw new NullPointerException();
-            else {
-                ThenCopy<Object> d = null;
-                CompletionNode p = null;
-                Object r;
-                while ((r = f.result) == null) {
-                    if (d == null)
-                        d = new ThenCopy<Object>(f, dst);
-                    else if (p == null)
-                        p = new CompletionNode(d);
-                    else if (UNSAFE.compareAndSwapObject
-                             (f, COMPLETIONS, p.next = f.completions, p))
-                        break;
-                }
-                if (r != null && (d == null || d.compareAndSet(0, 1))) {
-                    Throwable ex; Object t;
-                    if (r instanceof AltResult) {
-                        ex = ((AltResult)r).ex;
-                        t = null;
-                    }
-                    else {
-                        ex = null;
-                        t = r;
-                    }
-                    dst.internalComplete(t, ex);
-                }
-                f.helpPostComplete();
-            }
-            return dst;
-        }
-    }
-
-    /**
-     * Recursively constructs an Or'ed tree of CompletableFutures.
-     */
-    private static CompletableFuture<Object> anyTree(CompletableFuture<?>[] cfs,
-                                                     int lo, int hi) {
-        CompletableFuture<?> fst, snd;
-        int mid = (lo + hi) >>> 1;
-        if ((fst = (lo == mid   ? cfs[lo] : anyTree(cfs, lo,    mid))) == null ||
-            (snd = (hi == mid+1 ? cfs[hi] : anyTree(cfs, mid+1, hi))) == null)
-            throw new NullPointerException();
-        CompletableFuture<Object> dst = new CompletableFuture<Object>();
-        OrCompletion d = null;
-        CompletionNode p = null, q = null;
-        Object r;
-        while ((r = fst.result) == null && (r = snd.result) == null) {
-            if (d == null)
-                d = new OrCompletion(fst, snd, dst);
-            else if (p == null)
-                p = new CompletionNode(d);
-            else if (q == null) {
-                if (UNSAFE.compareAndSwapObject
-                    (fst, COMPLETIONS, p.next = fst.completions, p))
-                    q = new CompletionNode(d);
-            }
-            else if (UNSAFE.compareAndSwapObject
-                     (snd, COMPLETIONS, q.next = snd.completions, q))
-                break;
-        }
-        if ((r != null || (r = fst.result) != null ||
-             (r = snd.result) != null) &&
-            (d == null || d.compareAndSet(0, 1))) {
-            Throwable ex; Object t;
-            if (r instanceof AltResult) {
-                ex = ((AltResult)r).ex;
-                t = null;
-            }
-            else {
-                ex = null;
-                t = r;
-            }
-            dst.internalComplete(t, ex);
-        }
-        fst.helpPostComplete();
-        snd.helpPostComplete();
-        return dst;
+        return orTree(cfs, 0, cfs.length - 1);
     }
 
     /* ------------- Control and status methods -------------- */
@@ -2887,8 +2253,7 @@
      */
     public boolean cancel(boolean mayInterruptIfRunning) {
         boolean cancelled = (result == null) &&
-            UNSAFE.compareAndSwapObject
-            (this, RESULT, null, new AltResult(new CancellationException()));
+            internalComplete(new AltResult(new CancellationException()));
         postComplete();
         return cancelled || isCancelled();
     }
@@ -2940,11 +2305,12 @@
      * Forcibly causes subsequent invocations of method {@link #get()}
      * and related methods to throw the given exception, whether or
      * not already completed. This method is designed for use only in
-     * recovery actions, and even in such situations may result in
-     * ongoing dependent completions using established versus
+     * error recovery actions, and even in such situations may result
+     * in ongoing dependent completions using established versus
      * overwritten outcomes.
      *
      * @param ex the exception
+     * @throws NullPointerException if the exception is null
      */
     public void obtrudeException(Throwable ex) {
         if (ex == null) throw new NullPointerException();
@@ -2962,7 +2328,7 @@
      */
     public int getNumberOfDependents() {
         int count = 0;
-        for (CompletionNode p = completions; p != null; p = p.next)
+        for (Completion p = stack; p != null; p = p.next)
             ++count;
         return count;
     }
@@ -2993,20 +2359,19 @@
     // Unsafe mechanics
     private static final sun.misc.Unsafe UNSAFE;
     private static final long RESULT;
-    private static final long WAITERS;
-    private static final long COMPLETIONS;
+    private static final long STACK;
+    private static final long NEXT;
     static {
         try {
-            UNSAFE = sun.misc.Unsafe.getUnsafe();
+            final sun.misc.Unsafe u;
+            UNSAFE = u = sun.misc.Unsafe.getUnsafe();
             Class<?> k = CompletableFuture.class;
-            RESULT = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("result"));
-            WAITERS = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("waiters"));
-            COMPLETIONS = UNSAFE.objectFieldOffset
-                (k.getDeclaredField("completions"));
-        } catch (Exception e) {
-            throw new Error(e);
+            RESULT = u.objectFieldOffset(k.getDeclaredField("result"));
+            STACK = u.objectFieldOffset(k.getDeclaredField("stack"));
+            NEXT = u.objectFieldOffset
+                (Completion.class.getDeclaredField("next"));
+        } catch (Exception x) {
+            throw new Error(x);
         }
     }
 }
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletionStage.java	Wed Jul 05 20:00:07 2017 +0200
@@ -407,7 +407,7 @@
     /**
      * Returns a new CompletionStage that, when this and the other
      * given stage complete normally, executes the given action using
-     * the supplied executor
+     * the supplied executor.
      *
      * See the {@link CompletionStage} documentation for rules
      * covering exceptional completion.
@@ -569,7 +569,7 @@
     /**
      * Returns a new CompletionStage that, when either this or the
      * other given stage complete normally, executes the given action
-     * using supplied executor.
+     * using the supplied executor.
      *
      * See the {@link CompletionStage} documentation for rules
      * covering exceptional completion.
@@ -649,10 +649,15 @@
         (Function<Throwable, ? extends T> fn);
 
     /**
-     * Returns a new CompletionStage with the same result or exception
-     * as this stage, and when this stage completes, executes the
-     * given action with the result (or {@code null} if none) and the
-     * exception (or {@code null} if none) of this stage.
+     * Returns a new CompletionStage with the same result or exception as
+     * this stage, that executes the given action when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked with the
+     * result (or {@code null} if none) and the exception (or {@code null}
+     * if none) of this stage as arguments.  The returned stage is completed
+     * when the action returns.  If the supplied action itself encounters an
+     * exception, then the returned stage exceptionally completes with this
+     * exception unless this stage also completed exceptionally.
      *
      * @param action the action to perform
      * @return the new CompletionStage
@@ -661,12 +666,16 @@
         (BiConsumer<? super T, ? super Throwable> action);
 
     /**
-     * Returns a new CompletionStage with the same result or exception
-     * as this stage, and when this stage completes, executes the
-     * given action executes the given action using this stage's
-     * default asynchronous execution facility, with the result (or
-     * {@code null} if none) and the exception (or {@code null} if
-     * none) of this stage as arguments.
+     * Returns a new CompletionStage with the same result or exception as
+     * this stage, that executes the given action using this stage's
+     * default asynchronous execution facility when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked with the
+     * result (or {@code null} if none) and the exception (or {@code null}
+     * if none) of this stage as arguments.  The returned stage is completed
+     * when the action returns.  If the supplied action itself encounters an
+     * exception, then the returned stage exceptionally completes with this
+     * exception unless this stage also completed exceptionally.
      *
      * @param action the action to perform
      * @return the new CompletionStage
@@ -675,11 +684,16 @@
         (BiConsumer<? super T, ? super Throwable> action);
 
     /**
-     * Returns a new CompletionStage with the same result or exception
-     * as this stage, and when this stage completes, executes using
-     * the supplied Executor, the given action with the result (or
-     * {@code null} if none) and the exception (or {@code null} if
-     * none) of this stage as arguments.
+     * Returns a new CompletionStage with the same result or exception as
+     * this stage, that executes the given action using the supplied
+     * Executor when this stage completes.
+     *
+     * <p>When this stage is complete, the given action is invoked with the
+     * result (or {@code null} if none) and the exception (or {@code null}
+     * if none) of this stage as arguments.  The returned stage is completed
+     * when the action returns.  If the supplied action itself encounters an
+     * exception, then the returned stage exceptionally completes with this
+     * exception unless this stage also completed exceptionally.
      *
      * @param action the action to perform
      * @param executor the executor to use for asynchronous execution
@@ -693,9 +707,11 @@
      * Returns a new CompletionStage that, when this stage completes
      * either normally or exceptionally, is executed with this stage's
      * result and exception as arguments to the supplied function.
-     * The given function is invoked with the result (or {@code null}
-     * if none) and the exception (or {@code null} if none) of this
-     * stage when complete as arguments.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
      *
      * @param fn the function to use to compute the value of the
      * returned CompletionStage
@@ -710,9 +726,11 @@
      * either normally or exceptionally, is executed using this stage's
      * default asynchronous execution facility, with this stage's
      * result and exception as arguments to the supplied function.
-     * The given function is invoked with the result (or {@code null}
-     * if none) and the exception (or {@code null} if none) of this
-     * stage when complete as arguments.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
      *
      * @param fn the function to use to compute the value of the
      * returned CompletionStage
@@ -726,10 +744,12 @@
      * Returns a new CompletionStage that, when this stage completes
      * either normally or exceptionally, is executed using the
      * supplied executor, with this stage's result and exception as
-     * arguments to the supplied function.  The given function is
-     * invoked with the result (or {@code null} if none) and the
-     * exception (or {@code null} if none) of this stage when complete
-     * as arguments.
+     * arguments to the supplied function.
+     *
+     * <p>When this stage is complete, the given function is invoked
+     * with the result (or {@code null} if none) and the exception (or
+     * {@code null} if none) of this stage as arguments, and the
+     * function's result is used to complete the returned stage.
      *
      * @param fn the function to use to compute the value of the
      * returned CompletionStage
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/CertAndKeyGen.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -158,8 +158,8 @@
         // publicKey's format must be X.509 otherwise
         // the whole CertGen part of this class is broken.
         if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) {
-            throw new IllegalArgumentException("publicKey's is not X.509, but "
-                    + publicKey.getFormat());
+            throw new IllegalArgumentException("Public key format is "
+                + publicKey.getFormat() + ", must be X.509");
         }
     }
 
--- a/jdk/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -25,20 +25,20 @@
 
 package sun.util.cldr;
 
-import java.io.File;
 import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.text.spi.BreakIteratorProvider;
 import java.text.spi.CollatorProvider;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Locale;
-import java.util.ResourceBundle;
+import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.StringTokenizer;
-import java.util.spi.TimeZoneNameProvider;
 import sun.util.locale.provider.JRELocaleProviderAdapter;
 import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleDataMetaInfo;
 
 /**
  * LocaleProviderAdapter implementation for the CLDR locale data.
@@ -47,26 +47,31 @@
  * @author Naoto Sato
  */
 public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
-    private static final String LOCALE_DATA_JAR_NAME = "cldrdata.jar";
+
+    private final LocaleDataMetaInfo metaInfo;
 
     public CLDRLocaleProviderAdapter() {
-        final String sep = File.separator;
-        String localeDataJar = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("java.home"))
-                + sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
-
-        // Peek at the installed extension directory to see if the jar file for
-        // CLDR resources is installed or not.
-        final File f = new File(localeDataJar);
-        boolean result = AccessController.doPrivileged(
-                new PrivilegedAction<Boolean>() {
+        try {
+            metaInfo = AccessController.doPrivileged(new PrivilegedExceptionAction<LocaleDataMetaInfo>() {
                     @Override
-                    public Boolean run() {
-                        return f.exists();
+                public LocaleDataMetaInfo run() {
+                    for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
+                        if (ldmi.getType() == LocaleProviderAdapter.Type.CLDR) {
+                            return ldmi;
+                        }
+                    }
+                    return null;
                     }
                 });
-        if (!result) {
-            throw new UnsupportedOperationException();
+        }  catch (Exception e) {
+            // Catch any exception, and fail gracefully as if CLDR locales do not exist.
+            // It's ok ignore it if something wrong happens because there always is the
+            // JRE or FALLBACK LocaleProviderAdapter that will do the right thing.
+            throw new UnsupportedOperationException(e);
+        }
+
+        if (metaInfo == null) {
+            throw new UnsupportedOperationException("CLDR locale data could not be found.");
         }
     }
 
@@ -91,7 +96,7 @@
 
     @Override
     public Locale[] getAvailableLocales() {
-        Set<String> all = createLanguageTagSet("All");
+        Set<String> all = createLanguageTagSet("AvailableLocales");
         Locale[] locs = new Locale[all.size()];
         int index = 0;
         for (String tag : all) {
@@ -102,11 +107,10 @@
 
     @Override
     protected Set<String> createLanguageTagSet(String category) {
-        ResourceBundle rb = ResourceBundle.getBundle("sun.util.cldr.CLDRLocaleDataMetaInfo", Locale.ROOT);
-        if (rb.containsKey(category)) {
+        String supportedLocaleString = metaInfo.availableLanguageTags(category);
+        if (supportedLocaleString == null) {
             return Collections.emptySet();
         }
-        String supportedLocaleString = rb.getString(category);
         Set<String> tagset = new HashSet<>();
         StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
         while (tokens.hasMoreTokens()) {
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -56,7 +56,7 @@
     /**
      * SPI implementations map
      */
-    private ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap =
+    private final ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap =
             new ConcurrentHashMap<>();
 
     /**
@@ -167,7 +167,6 @@
                     avail.addAll(Arrays.asList(lsp.getAvailableLocales()));
                 }
             }
-            availableLocales = avail.toArray(new Locale[0]);
         }
 
         // assuming caller won't mutate the array.
@@ -178,7 +177,7 @@
      * A dummy locale service provider that indicates there is no
      * provider available
      */
-    private static NullProvider NULL_PROVIDER = new NullProvider();
+    private static final NullProvider NULL_PROVIDER = new NullProvider();
     private static class NullProvider extends LocaleServiceProvider {
         @Override
         public Locale[] getAvailableLocales() {
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -25,9 +25,9 @@
 
 package sun.util.locale.provider;
 
-import java.io.File;
 import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.text.spi.BreakIteratorProvider;
 import java.text.spi.CollatorProvider;
 import java.text.spi.DateFormatProvider;
@@ -37,6 +37,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Locale;
+import java.util.ServiceLoader;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.concurrent.ConcurrentHashMap;
@@ -58,8 +59,6 @@
  */
 public class JRELocaleProviderAdapter extends LocaleProviderAdapter implements ResourceBundleBasedAdapter {
 
-    private static final String LOCALE_DATA_JAR_NAME = "localedata.jar";
-
     private final ConcurrentMap<String, Set<String>> langtagSets
         = new ConcurrentHashMap<>();
 
@@ -356,26 +355,56 @@
     }
 
     protected Set<String> createLanguageTagSet(String category) {
-        String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString(category);
+        String supportedLocaleString = createSupportedLocaleString(category);
         if (supportedLocaleString == null) {
             return Collections.emptySet();
         }
         Set<String> tagset = new HashSet<>();
         StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
         while (tokens.hasMoreTokens()) {
-            String token = tokens.nextToken();
-            if (token.equals("|")) {
-                if (isNonENLangSupported()) {
-                    continue;
-                }
-                break;
-            }
-            tagset.add(token);
+            tagset.add(tokens.nextToken());
         }
 
         return tagset;
     }
 
+    private static String createSupportedLocaleString(String category) {
+        // Directly call English tags, as we know it's in the base module.
+        String supportedLocaleString = EnLocaleDataMetaInfo.getSupportedLocaleString(category);
+
+        // Use ServiceLoader to dynamically acquire installed locales' tags.
+        try {
+            String nonENTags = AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
+                @Override
+                public String run() {
+                    String tags = null;
+                    for (LocaleDataMetaInfo ldmi :
+                         ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
+                        if (ldmi.getType() == LocaleProviderAdapter.Type.JRE) {
+                            String t = ldmi.availableLanguageTags(category);
+                            if (t != null) {
+                                if (tags == null) {
+                                    tags = t;
+                                } else {
+                                    tags += " " + t;
+                                }
+                            }
+                        }
+                    }
+                    return tags;
+                }
+            });
+
+            if (nonENTags != null) {
+                supportedLocaleString += " " + nonENTags;
+            }
+        }  catch (Exception e) {
+            // catch any exception, and ignore them as if non-EN locales do not exist.
+        }
+
+        return supportedLocaleString;
+    }
+
     /**
      * Lazy load available locales.
      */
@@ -387,27 +416,17 @@
 
     private static Locale[] createAvailableLocales() {
         /*
-         * Gets the locale string list from LocaleDataMetaInfo class and then
+         * Gets the locale string list from LocaleDataMetaInfo classes and then
          * contructs the Locale array and a set of language tags based on the
          * locale string returned above.
          */
-        String supportedLocaleString = LocaleDataMetaInfo.getSupportedLocaleString("AvailableLocales");
+        String supportedLocaleString = createSupportedLocaleString("AvailableLocales");
 
         if (supportedLocaleString.length() == 0) {
             throw new InternalError("No available locales for JRE");
         }
 
-        /*
-         * Look for "|" and construct a new locale string list.
-         */
-        int barIndex = supportedLocaleString.indexOf('|');
-        StringTokenizer localeStringTokenizer;
-        if (isNonENLangSupported()) {
-            localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex)
-                    + supportedLocaleString.substring(barIndex + 1));
-        } else {
-            localeStringTokenizer = new StringTokenizer(supportedLocaleString.substring(0, barIndex));
-        }
+        StringTokenizer localeStringTokenizer = new StringTokenizer(supportedLocaleString);
 
         int length = localeStringTokenizer.countTokens();
         Locale[] locales = new Locale[length + 1];
@@ -430,39 +449,4 @@
         }
         return locales;
     }
-
-    private static volatile Boolean isNonENSupported = null;
-
-    /*
-     * Returns true if the non EN resources jar file exists in jre
-     * extension directory. @returns true if the jar file is there. Otherwise,
-     * returns false.
-     */
-    private static boolean isNonENLangSupported() {
-        if (isNonENSupported == null) {
-            synchronized (JRELocaleProviderAdapter.class) {
-                if (isNonENSupported == null) {
-                    final String sep = File.separator;
-                    String localeDataJar =
-                            java.security.AccessController.doPrivileged(
-                            new sun.security.action.GetPropertyAction("java.home"))
-                            + sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
-
-                    /*
-                     * Peek at the installed extension directory to see if
-                     * localedata.jar is installed or not.
-                     */
-                    final File f = new File(localeDataJar);
-                    isNonENSupported =
-                        AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-                            @Override
-                            public Boolean run() {
-                                return f.exists();
                             }
-                        });
-               }
-            }
-        }
-        return isNonENSupported;
-    }
-}
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template	Wed Jul 05 20:00:07 2017 +0200
@@ -30,19 +30,17 @@
  * each resource in sun.util.resources & sun.text.resources.
  * It is used to avoid loading non-existent localized resources so that
  * jar files won't be opened unnecessary to look up them.
- *
- * @since 1.6
  */
-package sun.util.locale.provider;
+package #Package#;
 
 import java.util.HashMap;
-
-
-public class LocaleDataMetaInfo {
+import java.util.Map;
+import sun.util.locale.provider.LocaleDataMetaInfo;
+import static sun.util.locale.provider.LocaleProviderAdapter.Type;
 
-    private static final HashMap<String, String> resourceNameToLocales =
-        new HashMap<String, String>(7);
+public class #Lang#LocaleDataMetaInfo implements LocaleDataMetaInfo {
 
+    private static final Map<String, String> resourceNameToLocales = new HashMap<>(9);
 
     static {
         /* During JDK build time, #XXX_YYY# will be replaced by a string contain all the locales
@@ -52,38 +50,51 @@
            look up locale string such as "en" could be based on if it contains " en ".
         */
         resourceNameToLocales.put("FormatData",
-                                  " #FormatData_ENLocales# | #FormatData_NonENLocales# ");
+                                  " #FormatData_Locales# ");
 
         resourceNameToLocales.put("CollationData",
-                                  " #CollationData_ENLocales# | #CollationData_NonENLocales# ");
+                                  " #CollationData_Locales# ");
 
         resourceNameToLocales.put("BreakIteratorInfo",
-                                  " #BreakIteratorInfo_ENLocales# | #BreakIteratorInfo_NonENLocales# ");
+                                  " #BreakIteratorInfo_Locales# ");
 
         resourceNameToLocales.put("BreakIteratorRules",
-                                  " #BreakIteratorRules_ENLocales# | #BreakIteratorRules_NonENLocales# ");
+                                  " #BreakIteratorRules_Locales# ");
 
         resourceNameToLocales.put("TimeZoneNames",
-                                  " #TimeZoneNames_ENLocales# | #TimeZoneNames_NonENLocales# ");
+                                  " #TimeZoneNames_Locales# ");
 
         resourceNameToLocales.put("LocaleNames",
-                                  " #LocaleNames_ENLocales# | #LocaleNames_NonENLocales# ");
+                                  " #LocaleNames_Locales# ");
 
         resourceNameToLocales.put("CurrencyNames",
-                                  " #CurrencyNames_ENLocales# | #CurrencyNames_NonENLocales# ");
+                                  " #CurrencyNames_Locales# ");
 
         resourceNameToLocales.put("CalendarData",
-                                  " #CalendarData_ENLocales# | #CalendarData_NonENLocales# ");
+                                  " #CalendarData_Locales# ");
 
         resourceNameToLocales.put("AvailableLocales",
-                                  " #AvailableLocales_ENLocales# | #AvailableLocales_NonENLocales# ");
+                                  " #AvailableLocales_Locales# ");
     }
 
     /*
+     * Gets the supported locales string based on the availability of
+     * locale data resource bundles for each resource name.
+     *
      * @param resourceName the resource name
      * @return the supported locale string for the passed in resource.
      */
     public static String getSupportedLocaleString(String resourceName) {
-        return resourceNameToLocales.get(resourceName);
+        return resourceNameToLocales.getOrDefault(resourceName, "");
+    }
+
+    @Override
+    public Type getType() {
+        return Type.JRE;
+}
+
+    @Override
+    public String availableLanguageTags(String category) {
+        return getSupportedLocaleString(category);
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.util.locale.provider;
+
+/**
+ * LocaleData meta info SPI
+ *
+ * @author Naoto Sato
+ */
+public interface LocaleDataMetaInfo {
+
+    /**
+     * Returns the type of LocaleProviderAdapter for which this LocaleData
+     * provides the data.
+     * @return type The type of the adapter.
+     */
+    public LocaleProviderAdapter.Type getType();
+
+    /**
+     * Returns the string concatenation of the supported language tags in
+     * this LocaleData instance
+     * @param category category of the locale data.
+     * @return concatenated language tags, separated by a space.
+     */
+    public String availableLanguageTags(String category);
+}
--- a/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/util/resources/LocaleData.java	Wed Jul 05 20:00:07 2017 +0200
@@ -50,7 +50,6 @@
 import java.util.ResourceBundle;
 import java.util.Set;
 import sun.util.locale.provider.JRELocaleProviderAdapter;
-import sun.util.locale.provider.LocaleDataMetaInfo;
 import sun.util.locale.provider.LocaleProviderAdapter;
 import static sun.util.locale.provider.LocaleProviderAdapter.Type.CLDR;
 import static sun.util.locale.provider.LocaleProviderAdapter.Type.JRE;
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java	Wed Jul 05 20:00:07 2017 +0200
@@ -94,10 +94,12 @@
 
     @Override
     public void addDropTarget(DropTarget dt) {
+        getLwTarget().addDropTarget(dt);
     }
 
     @Override
     public void removeDropTarget(DropTarget dt) {
+        getLwTarget().removeDropTarget(dt);
     }
 
     @Override
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java	Wed Jul 05 20:00:07 2017 +0200
@@ -688,6 +688,11 @@
     @Override
     public DragSourceContextPeer createDragSourceContextPeer(
             DragGestureEvent dge) throws InvalidDnDOperationException {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
+        if (f != null) {
+            return f.createDragSourceContextPeer(dge);
+        }
+
         return CDragSourceContextPeer.createDragSourceContextPeer(dge);
     }
 
@@ -696,6 +701,11 @@
     public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
             Class<T> abstractRecognizerClass, DragSource ds, Component c,
             int srcActions, DragGestureListener dgl) {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(c);
+        if (f != null) {
+            return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
+        }
+
         DragGestureRecognizer dgr = null;
 
         // Create a new mouse drag gesture recognizer if we have a class match:
--- a/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093: \u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58(&S)
-FileChooser.openButton.textAndMnemonic=\u958B\u304F(&O)
+FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58
+FileChooser.openButton.textAndMnemonic=\u958B\u304F
 FileChooser.saveDialogTitle.textAndMnemonic=\u4FDD\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u304F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u30D8\u30EB\u30D7(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u304F(&O)
+FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u304F
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
--- a/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC74C: \uC9C0\uC815\uD55C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uB294 \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC2ED\uC2DC\uC624.
 FileChooser.acceptAllFileFilter.textAndMnemonic=\uBAA8\uB4E0 \uD30C\uC77C
 FileChooser.cancelButton.textAndMnemonic=\uCDE8\uC18C
-FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5(&S)
-FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30(&O)
+FileChooser.saveButton.textAndMnemonic=\uC800\uC7A5
+FileChooser.openButton.textAndMnemonic=\uC5F4\uAE30
 FileChooser.saveDialogTitle.textAndMnemonic=\uC800\uC7A5
 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30
 FileChooser.updateButton.textAndMnemonic=\uC5C5\uB370\uC774\uD2B8(&U)
 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30(&O)
+FileChooser.directoryOpenButton.textAndMnemonic=\uC5F4\uAE30
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
--- a/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic=\u65E0\u6CD5\u91CD\u547D\u540D{0}: \u5DF2\u5B58\u5728\u5177\u6709\u6240\u6307\u5B9A\u540D\u79F0\u7684\u6587\u4EF6\u3002\u8BF7\u6307\u5B9A\u5176\u4ED6\u6587\u4EF6\u540D\u3002
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u6240\u6709\u6587\u4EF6
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58(&S)
-FileChooser.openButton.textAndMnemonic=\u6253\u5F00(&O)
+FileChooser.saveButton.textAndMnemonic=\u4FDD\u5B58
+FileChooser.openButton.textAndMnemonic=\u6253\u5F00
 FileChooser.saveDialogTitle.textAndMnemonic=\u4FDD\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u6253\u5F00
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u5E2E\u52A9(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u6253\u5F00(&O)
+FileChooser.directoryOpenButton.textAndMnemonic=\u6253\u5F00
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
--- a/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -42,13 +42,13 @@
 FileChooser.renameErrorFileExists.textAndMnemonic=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0}: \u5DF2\u7D93\u5B58\u5728\u60A8\u6240\u6307\u5B9A\u540D\u7A31\u7684\u6A94\u6848\u3002\u8ACB\u6307\u5B9A\u4E0D\u540C\u7684\u540D\u7A31\u3002
 FileChooser.acceptAllFileFilter.textAndMnemonic=\u6240\u6709\u6A94\u6848
 FileChooser.cancelButton.textAndMnemonic=\u53D6\u6D88
-FileChooser.saveButton.textAndMnemonic=\u5132\u5B58(&S)
-FileChooser.openButton.textAndMnemonic=\u958B\u555F(&O)
+FileChooser.saveButton.textAndMnemonic=\u5132\u5B58
+FileChooser.openButton.textAndMnemonic=\u958B\u555F
 FileChooser.saveDialogTitle.textAndMnemonic=\u5132\u5B58
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u555F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0(&U)
 FileChooser.helpButton.textAndMnemonic=\u8AAA\u660E(&H)
-FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u555F(&O)
+FileChooser.directoryOpenButton.textAndMnemonic=\u958B\u555F
 
 # File Size Units
 FileChooser.fileSizeKiloBytes={0} KB
--- a/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java	Wed Jul 05 20:00:07 2017 +0200
@@ -968,20 +968,22 @@
      */
     public static ICC_Profile getInstance(String fileName) throws IOException {
         ICC_Profile thisProfile;
-        FileInputStream fis = null;
+        InputStream is = null;
 
 
         File f = getProfileFile(fileName);
         if (f != null) {
-            fis = new FileInputStream(f);
+            is = new FileInputStream(f);
+        } else {
+            is = getStandardProfileInputStream(fileName);
         }
-        if (fis == null) {
+        if (is == null) {
             throw new IOException("Cannot open file " + fileName);
         }
 
-        thisProfile = getInstance(fis);
+        thisProfile = getInstance(is);
 
-        fis.close();    /* close the file */
+        is.close();    /* close the file */
 
         return thisProfile;
     }
@@ -1086,28 +1088,17 @@
 
     void activateDeferredProfile() throws ProfileDataException {
         byte profileData[];
-        FileInputStream fis;
         final String fileName = deferralInfo.filename;
 
         profileActivator = null;
         deferralInfo = null;
-        PrivilegedAction<FileInputStream> pa = new PrivilegedAction<FileInputStream>() {
-            public FileInputStream run() {
-                File f = getStandardProfileFile(fileName);
-                if (f != null) {
-                    try {
-                        return new FileInputStream(f);
-                    } catch (FileNotFoundException e) {}
-                }
-                return null;
-            }
-        };
-        if ((fis = AccessController.doPrivileged(pa)) == null) {
+        InputStream is = getStandardProfileInputStream(fileName);
+        if (is == null) {
             throw new ProfileDataException("Cannot open file " + fileName);
         }
         try {
-            profileData = getProfileDataFromStream(fis);
-            fis.close();    /* close the file */
+            profileData = getProfileDataFromStream(is);
+            is.close();    /* close the file */
         }
         catch (IOException e) {
             ProfileDataException pde = new
@@ -1810,10 +1801,12 @@
      * fileName may be an absolute or a relative file specification.
      * Relative file names are looked for in several places: first, relative
      * to any directories specified by the java.iccprofile.path property;
-     * second, relative to any directories specified by the java.class.path
-     * property; finally, in a directory used to store profiles always
-     * available, such as a profile for sRGB.  Built-in profiles use .pf as
-     * the file name extension for profiles, e.g. sRGB.pf.
+     * second, relative to any directories specified by the java.class.path.
+     * The built-in profile files are now loaded as resources, since they
+     * may not be individual disk files, and so this method will not find
+     * these and on a null return, the caller needs to try as resources.
+     * Built-in profiles use .pf as the file name extension for profiles,
+     * e.g. sRGB.pf.
      */
     private static File getProfileFile(String fileName) {
         String path, dir, fullPath;
@@ -1849,30 +1842,22 @@
                         fullPath = dir + File.separatorChar + fileName;
                     f = new File(fullPath);
                 }
-            }
+        }
 
-        if ((f == null) || (!f.isFile())) {
-            /* try the directory of built-in profiles */
-            f = getStandardProfileFile(fileName);
+        if (f != null && !f.isFile()) {
+            f = null;
         }
-        if (f != null && f.isFile()) {
-            return f;
-        }
-        return null;
+        return f;
     }
 
     /**
-     * Returns a file object corresponding to a built-in profile
+     * Returns a stream corresponding to a built-in profile
      * specified by fileName.
      * If there is no built-in profile with such name, then the method
      * returns null.
      */
-    private static File getStandardProfileFile(String fileName) {
-        String dir = System.getProperty("java.home") +
-            File.separatorChar + "lib" + File.separatorChar + "cmm";
-        String fullPath = dir + File.separatorChar + fileName;
-        File f = new File(fullPath);
-        return (f.isFile() && isChildOf(f, dir)) ? f : null;
+    private static InputStream getStandardProfileInputStream(String fileName) {
+        return PCMM.class.getResourceAsStream("profiles/" + fileName);
     }
 
     /**
@@ -1901,7 +1886,7 @@
     private static boolean standardProfileExists(final String fileName) {
         return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                 public Boolean run() {
-                    return getStandardProfileFile(fileName) != null;
+                    return PCMM.class.getResource("profiles/"+fileName) != null;
                 }
             });
     }
--- a/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/ImageReader.java	Wed Jul 05 20:00:07 2017 +0200
@@ -2806,7 +2806,7 @@
      * @param imageTypes an <code>Iterator</code> of
      * <code>ImageTypeSpecifier</code>s indicating the legal image
      * types, with the default first.
-     * @param width the true width of the image or tile begin decoded.
+     * @param width the true width of the image or tile being decoded.
      * @param height the true width of the image or tile being decoded.
      *
      * @return the <code>BufferedImage</code> to which decoded pixel
--- a/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -305,6 +305,9 @@
     /**
      * Check that the node is either <code>null</code> or an
      * <code>IIOMetadataNode</code>.
+     *
+     * @throws DOMException if {@code node} is not {@code null} and not an
+     * instance of {@code IIOMetadataNode}
      */
     private void checkNode(Node node) throws DOMException {
         if (node == null) {
--- a/jdk/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/print/attribute/standard/DialogTypeSelection.java	Wed Jul 05 20:00:07 2017 +0200
@@ -67,7 +67,7 @@
         COMMON = new DialogTypeSelection(1);
 
     /**
-     * Construct a new dialog type selection enumeration value with the
+     * Constructs a new dialog type selection enumeration value with the
      * given integer value.
      *
      * @param  value  Integer value.
@@ -101,7 +101,7 @@
 
 
    /**
-     * Get the printing attribute class which is to be used as the "category"
+     * Gets the printing attribute class which is to be used as the "category"
      * for this printing attribute value.
      * <P>
      * For class DialogTypeSelection the category is class
@@ -116,7 +116,7 @@
 
 
     /**
-     * Get the name of the category of which this attribute value is an
+     * Gets the name of the category of which this attribute value is an
      * instance.
      * <P>
      * For class DialogTypeSelection the category name is
--- a/jdk/src/java.desktop/share/classes/javax/swing/JSlider.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JSlider.java	Wed Jul 05 20:00:07 2017 +0200
@@ -138,8 +138,11 @@
     /**
      * {@code Dictionary} of what labels to draw at which values
      */
-    private Dictionary<Integer, JComponent> labelTable;
-
+    @SuppressWarnings("rawtypes")
+    private Dictionary labelTable;
+    // For better source compatibility, the labelTable field and
+    // associated getter and setter methods are being left as raw
+    // types.
 
     /**
      * The changeListener (no suffix) is the listener we add to the
@@ -773,10 +776,10 @@
         }
 
         // Check that there is a label with such image
-        Enumeration<JComponent> elements = labelTable.elements();
+        Enumeration<?> elements = labelTable.elements();
 
         while (elements.hasMoreElements()) {
-            JComponent component = elements.nextElement();
+            Component component = (Component) elements.nextElement();
 
             if (component instanceof JLabel) {
                 JLabel label = (JLabel) component;
@@ -797,7 +800,8 @@
      * @return the <code>Dictionary</code> containing labels and
      *    where to draw them
      */
-    public Dictionary<Integer, JComponent> getLabelTable() {
+    @SuppressWarnings("rawtypes")
+    public Dictionary getLabelTable() {
 /*
         if ( labelTable == null && getMajorTickSpacing() > 0 ) {
             setLabelTable( createStandardLabels( getMajorTickSpacing() ) );
@@ -830,8 +834,9 @@
      *    attribute: visualUpdate true
      *  description: Specifies what labels will be drawn for any given value.
      */
-    public void setLabelTable( Dictionary<Integer, JComponent> labels ) {
-        Dictionary<Integer, JComponent> oldTable = labelTable;
+    @SuppressWarnings("rawtypes")
+    public void setLabelTable( Dictionary labels ) {
+        Dictionary oldTable = labelTable;
         labelTable = labels;
         updateLabelUIs();
         firePropertyChange("labelTable", oldTable, labelTable );
@@ -852,25 +857,27 @@
      * @see JComponent#updateUI
      */
     protected void updateLabelUIs() {
-        Dictionary<Integer, JComponent> labelTable = getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary labelTable = getLabelTable();
 
         if (labelTable == null) {
             return;
         }
-        Enumeration<Integer> labels = labelTable.keys();
+        Enumeration<?> labels = labelTable.keys();
         while ( labels.hasMoreElements() ) {
-            JComponent component = labelTable.get(labels.nextElement());
+            JComponent component = (JComponent) labelTable.get(labels.nextElement());
             component.updateUI();
             component.setSize(component.getPreferredSize());
         }
     }
 
     private void updateLabelSizes() {
-        Dictionary<Integer, JComponent> labelTable = getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary labelTable = getLabelTable();
         if (labelTable != null) {
-            Enumeration<JComponent> labels = labelTable.elements();
+            Enumeration<?> labels = labelTable.elements();
             while (labels.hasMoreElements()) {
-                JComponent component = labels.nextElement();
+                JComponent component = (JComponent) labels.nextElement();
                 component.setSize(component.getPreferredSize());
             }
         }
@@ -982,13 +989,13 @@
                 if ( e.getPropertyName().equals( "minimum" ) ||
                      e.getPropertyName().equals( "maximum" ) ) {
 
-                    Enumeration<Integer> keys = getLabelTable().keys();
+                    Enumeration<?> keys = getLabelTable().keys();
                     Hashtable<Integer, JComponent> hashtable = new Hashtable<>();
 
                     // Save the labels that were added by the developer
                     while ( keys.hasMoreElements() ) {
-                        Integer key = keys.nextElement();
-                        JComponent value = labelTable.get(key);
+                        Integer key = (Integer) keys.nextElement();
+                        JComponent value = (JComponent) labelTable.get(key);
                         if ( !(value instanceof LabelUIResource) ) {
                             hashtable.put( key, value );
                         }
@@ -1000,7 +1007,7 @@
                     // Add the saved labels
                     keys = hashtable.keys();
                     while ( keys.hasMoreElements() ) {
-                        Integer key = keys.nextElement();
+                        Integer key = (Integer) keys.nextElement();
                         put( key, hashtable.get( key ) );
                     }
 
@@ -1017,7 +1024,8 @@
 
         SmartHashtable table = new SmartHashtable( increment, start );
 
-        Dictionary<Integer, JComponent> labelTable = getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary labelTable = getLabelTable();
 
         if (labelTable != null && (labelTable instanceof PropertyChangeListener)) {
             removePropertyChangeListener((PropertyChangeListener) labelTable);
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java	Wed Jul 05 20:00:07 2017 +0200
@@ -670,7 +670,8 @@
      * @param rowData           the data for the new table
      * @param columnNames       names of each column
      */
-    public JTable(Vector<Vector<Object>> rowData, Vector<Object> columnNames) {
+    @SuppressWarnings("rawtypes")
+    public JTable(Vector<? extends Vector> rowData, Vector<?> columnNames) {
         this(new DefaultTableModel(rowData, columnNames));
     }
 
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSliderUI.java	Wed Jul 05 20:00:07 2017 +0200
@@ -397,13 +397,14 @@
     protected boolean labelsHaveSameBaselines() {
         if (!checkedLabelBaselines) {
             checkedLabelBaselines = true;
-            Dictionary<?, JComponent> dictionary = slider.getLabelTable();
+            @SuppressWarnings("rawtypes")
+            Dictionary dictionary = slider.getLabelTable();
             if (dictionary != null) {
                 sameLabelBaselines = true;
-                Enumeration<JComponent> elements = dictionary.elements();
+                Enumeration<?> elements = dictionary.elements();
                 int baseline = -1;
                 while (elements.hasMoreElements()) {
-                    JComponent label = elements.nextElement();
+                    JComponent label = (JComponent) elements.nextElement();
                     Dimension pref = label.getPreferredSize();
                     int labelBaseline = label.getBaseline(pref.width,
                                                           pref.height);
@@ -758,12 +759,13 @@
     }
 
     protected int getWidthOfWidestLabel() {
-        Dictionary<?, JComponent> dictionary = slider.getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary dictionary = slider.getLabelTable();
         int widest = 0;
         if ( dictionary != null ) {
             Enumeration<?> keys = dictionary.keys();
             while ( keys.hasMoreElements() ) {
-                JComponent label = dictionary.get(keys.nextElement());
+                JComponent label = (JComponent) dictionary.get(keys.nextElement());
                 widest = Math.max( label.getPreferredSize().width, widest );
             }
         }
@@ -771,12 +773,13 @@
     }
 
     protected int getHeightOfTallestLabel() {
-        Dictionary<?, JComponent> dictionary = slider.getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary dictionary = slider.getLabelTable();
         int tallest = 0;
         if ( dictionary != null ) {
             Enumeration<?> keys = dictionary.keys();
             while ( keys.hasMoreElements() ) {
-                JComponent label = dictionary.get(keys.nextElement());
+                JComponent label = (JComponent) dictionary.get(keys.nextElement());
                 tallest = Math.max( label.getPreferredSize().height, tallest );
             }
         }
@@ -847,18 +850,19 @@
      * @since 1.6
      */
     protected Integer getHighestValue() {
-        Dictionary<Integer, ?> dictionary = slider.getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary dictionary = slider.getLabelTable();
 
         if (dictionary == null) {
             return null;
         }
 
-        Enumeration<Integer> keys = dictionary.keys();
+        Enumeration<?> keys = dictionary.keys();
 
         Integer max = null;
 
         while (keys.hasMoreElements()) {
-            Integer i = keys.nextElement();
+            Integer i = (Integer) keys.nextElement();
 
             if (max == null || i > max) {
                 max = i;
@@ -876,18 +880,19 @@
      * @since 1.6
      */
     protected Integer getLowestValue() {
-        Dictionary<Integer, JComponent> dictionary = slider.getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary dictionary = slider.getLabelTable();
 
         if (dictionary == null) {
             return null;
         }
 
-        Enumeration<Integer> keys = dictionary.keys();
+        Enumeration<?> keys = dictionary.keys();
 
         Integer min = null;
 
         while (keys.hasMoreElements()) {
-            Integer i = keys.nextElement();
+            Integer i = (Integer) keys.nextElement();
 
             if (min == null || i < min) {
                 min = i;
@@ -1134,17 +1139,18 @@
     public void paintLabels( Graphics g ) {
         Rectangle labelBounds = labelRect;
 
-        Dictionary<Integer, JComponent> dictionary = slider.getLabelTable();
+        @SuppressWarnings("rawtypes")
+        Dictionary dictionary = slider.getLabelTable();
         if ( dictionary != null ) {
-            Enumeration<Integer> keys = dictionary.keys();
+            Enumeration<?> keys = dictionary.keys();
             int minValue = slider.getMinimum();
             int maxValue = slider.getMaximum();
             boolean enabled = slider.isEnabled();
             while ( keys.hasMoreElements() ) {
-                Integer key = keys.nextElement();
+                Integer key = (Integer)keys.nextElement();
                 int value = key.intValue();
                 if (value >= minValue && value <= maxValue) {
-                    JComponent label = dictionary.get(key);
+                    JComponent label = (JComponent) dictionary.get(key);
                     label.setEnabled(enabled);
 
                     if (label instanceof JLabel) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSliderUI.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSliderUI.java	Wed Jul 05 20:00:07 2017 +0200
@@ -269,7 +269,7 @@
                 centerY += valueHeight + 2;
                 centerY += trackHeight + trackInsets.top + trackInsets.bottom;
                 centerY += tickHeight + 2;
-                JComponent label = slider.getLabelTable().elements().nextElement();
+                JComponent label = (JComponent) slider.getLabelTable().elements().nextElement();
                 Dimension pref = label.getPreferredSize();
                 return centerY + label.getBaseline(pref.width, pref.height);
             }
@@ -291,7 +291,7 @@
                     int trackHeight = contentHeight - valueHeight;
                     int yPosition = yPositionForValue(value.intValue(), trackY,
                                                       trackHeight);
-                    JComponent label = slider.getLabelTable().get(value);
+                    JComponent label = (JComponent) slider.getLabelTable().get(value);
                     Dimension pref = label.getPreferredSize();
                     return yPosition - pref.height / 2 +
                             label.getBaseline(pref.width, pref.height);
@@ -392,7 +392,8 @@
                 trackRect.x = insetCache.left;
                 trackRect.width = contentRect.width;
 
-                Dictionary<Integer, JComponent> dictionary = slider.getLabelTable();
+                @SuppressWarnings("rawtypes")
+                Dictionary dictionary = slider.getLabelTable();
                 if (dictionary != null) {
                     int minValue = slider.getMinimum();
                     int maxValue = slider.getMaximum();
@@ -402,9 +403,9 @@
                     // slider range.
                     int firstLblIdx = Integer.MAX_VALUE;
                     int lastLblIdx = Integer.MIN_VALUE;
-                    for (Enumeration<Integer> keys = dictionary.keys();
+                    for (Enumeration<?> keys = dictionary.keys();
                             keys.hasMoreElements(); ) {
-                        int keyInt = keys.nextElement().intValue();
+                        int keyInt = ((Integer)keys.nextElement()).intValue();
                         if (keyInt >= minValue && keyInt < firstLblIdx) {
                             firstLblIdx = keyInt;
                         }
@@ -517,7 +518,7 @@
     private int getPadForLabel(int i) {
         int pad = 0;
 
-        JComponent c = slider.getLabelTable().get(i);
+        JComponent c = (JComponent) slider.getLabelTable().get(i);
         if (c != null) {
             int centerX = xPositionForValue(i);
             int cHalfWidth = c.getPreferredSize().width / 2;
--- a/jdk/src/java.desktop/share/classes/javax/swing/table/DefaultTableModel.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/table/DefaultTableModel.java	Wed Jul 05 20:00:07 2017 +0200
@@ -70,10 +70,18 @@
      * The <code>Vector</code> of <code>Vectors</code> of
      * <code>Object</code> values.
      */
-    protected Vector<Vector<Object>>    dataVector;
+    @SuppressWarnings("rawtypes")
+    protected Vector<Vector>    dataVector;
 
     /** The <code>Vector</code> of column identifiers. */
-    protected Vector<Object>    columnIdentifiers;
+    @SuppressWarnings("rawtypes")
+    protected Vector    columnIdentifiers;
+    // Unfortunately, for greater source compatibility the inner-most
+    // Vector in the two fields above is being left raw. The Vector is
+    // read as well as written so using Vector<?> is not suitable and
+    // using Vector<Object> (without adding copying of input Vectors),
+    // would disallow existing code that used, say, a Vector<String>
+    // as an input parameter.
 
 //
 // Constructors
@@ -121,7 +129,7 @@
      * @see #setDataVector
      * @see #setValueAt
      */
-    public DefaultTableModel(Vector<Object> columnNames, int rowCount) {
+    public DefaultTableModel(Vector<?> columnNames, int rowCount) {
         setDataVector(newVector(rowCount), columnNames);
     }
 
@@ -156,7 +164,8 @@
      * @see #getDataVector
      * @see #setDataVector
      */
-    public DefaultTableModel(Vector<Vector<Object>> data, Vector<Object> columnNames) {
+    @SuppressWarnings("rawtypes")
+    public DefaultTableModel(Vector<? extends Vector> data, Vector<?> columnNames) {
         setDataVector(data, columnNames);
     }
 
@@ -191,7 +200,8 @@
      * @see #newRowsAdded
      * @see #setDataVector
      */
-    public Vector<Vector<Object>> getDataVector() {
+    @SuppressWarnings("rawtypes")
+    public Vector<Vector> getDataVector() {
         return dataVector;
     }
 
@@ -219,9 +229,10 @@
      * @param   columnIdentifiers     the names of the columns
      * @see #getDataVector
      */
-    public void setDataVector(Vector<Vector<Object>> dataVector,
-                              Vector<Object> columnIdentifiers) {
-        this.dataVector = nonNullVector(dataVector);
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public void setDataVector(Vector<? extends Vector> dataVector,
+                              Vector<?> columnIdentifiers) {
+        this.dataVector = nonNullVector((Vector<Vector>)dataVector);
         this.columnIdentifiers = nonNullVector(columnIdentifiers);
         justifyRows(0, getRowCount());
         fireTableStructureChanged();
@@ -267,7 +278,7 @@
             if (dataVector.elementAt(i) == null) {
                 dataVector.setElementAt(new Vector<>(), i);
             }
-            ((Vector)dataVector.elementAt(i)).setSize(getColumnCount());
+            dataVector.elementAt(i).setSize(getColumnCount());
         }
     }
 
@@ -350,7 +361,7 @@
      *
      * @param   rowData          optional data of the row being added
      */
-    public void addRow(Vector<Object> rowData) {
+    public void addRow(Vector<?> rowData) {
         insertRow(getRowCount(), rowData);
     }
 
@@ -374,7 +385,7 @@
      * @param   rowData         optional data of the row being added
      * @exception  ArrayIndexOutOfBoundsException  if the row was invalid
      */
-    public void insertRow(int row, Vector<Object> rowData) {
+    public void insertRow(int row, Vector<?> rowData) {
         dataVector.insertElementAt(rowData, row);
         justifyRows(row, row+1);
         fireTableRowsInserted(row, row);
@@ -484,7 +495,7 @@
      *                          to zero columns
      * @see #setNumRows
      */
-    public void setColumnIdentifiers(Vector<Object> columnIdentifiers) {
+    public void setColumnIdentifiers(Vector<?> columnIdentifiers) {
         setDataVector(dataVector, columnIdentifiers);
     }
 
@@ -550,7 +561,8 @@
      * @param   columnName the identifier of the column being added
      * @param   columnData       optional data of the column being added
      */
-    public void addColumn(Object columnName, Vector<Object> columnData) {
+    @SuppressWarnings("unchecked") // Adding element to raw columnIdentifiers
+    public void addColumn(Object columnName, Vector<?> columnData) {
         columnIdentifiers.addElement(columnName);
         if (columnData != null) {
             int columnSize = columnData.size();
@@ -652,6 +664,7 @@
      *               column was given
      */
     public Object getValueAt(int row, int column) {
+        @SuppressWarnings("unchecked")
         Vector<Object> rowVector = dataVector.elementAt(row);
         return rowVector.elementAt(column);
     }
@@ -668,6 +681,7 @@
      *               column was given
      */
     public void setValueAt(Object aValue, int row, int column) {
+        @SuppressWarnings("unchecked")
         Vector<Object> rowVector = dataVector.elementAt(row);
         rowVector.setElementAt(aValue, column);
         fireTableCellUpdated(row, column);
--- a/jdk/src/java.desktop/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/tree/DefaultMutableTreeNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1317,7 +1317,7 @@
     }
 
     private final class PreorderEnumeration implements Enumeration<TreeNode> {
-        private final Stack<Enumeration<TreeNode>> stack = new Stack<>();
+        private final Stack<Enumeration<? extends TreeNode>> stack = new Stack<>();
 
         public PreorderEnumeration(TreeNode rootNode) {
             super();
@@ -1331,10 +1331,9 @@
         }
 
         public TreeNode nextElement() {
-            Enumeration<TreeNode> enumer = stack.peek();
+            Enumeration<? extends TreeNode> enumer = stack.peek();
             TreeNode    node = enumer.nextElement();
-            @SuppressWarnings("unchecked")
-            Enumeration<TreeNode> children = node.children();
+            Enumeration<? extends TreeNode> children = node.children();
 
             if (!enumer.hasMoreElements()) {
                 stack.pop();
@@ -1351,7 +1350,7 @@
 
     final class PostorderEnumeration implements Enumeration<TreeNode> {
         protected TreeNode root;
-        protected Enumeration<TreeNode> children;
+        protected Enumeration<? extends TreeNode> children;
         protected Enumeration<TreeNode> subtree;
 
         public PostorderEnumeration(TreeNode rootNode) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/tree/TreeNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/javax/swing/tree/TreeNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, 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
@@ -99,5 +99,5 @@
      *
      * @return              the children of the receiver as an {@code Enumeration}
      */
-    Enumeration<TreeNode> children();
+    Enumeration<? extends TreeNode> children();
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/LightweightFrame.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/LightweightFrame.java	Wed Jul 05 20:00:07 2017 +0200
@@ -25,6 +25,7 @@
 
 package sun.awt;
 
+import java.awt.Component;
 import java.awt.Container;
 import java.awt.Frame;
 import java.awt.Graphics;
@@ -33,6 +34,13 @@
 import java.awt.MenuComponent;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.InvalidDnDOperationException;
+import java.awt.dnd.peer.DragSourceContextPeer;
 import java.awt.peer.FramePeer;
 
 /**
@@ -169,4 +177,27 @@
         hostW = w;
         hostH = h;
     }
+
+    /**
+     * Create a drag gesture recognizer for the lightweight frame.
+     */
+    public abstract <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> abstractRecognizerClass,
+            DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl);
+
+    /**
+     * Create a drag source context peer for the lightweight frame.
+     */
+    public abstract DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException;
+
+    /**
+     * Adds a drop target to the lightweight frame.
+     */
+    public abstract void addDropTarget(DropTarget dt);
+
+    /**
+     * Removes a drop target from the lightweight frame.
+     */
+    public abstract void removeDropTarget(DropTarget dt);
 }
--- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java	Wed Jul 05 20:00:07 2017 +0200
@@ -2014,6 +2014,19 @@
         return isInstanceOf(cls.getSuperclass(), type);
     }
 
+    protected static LightweightFrame getLightweightFrame(Component c) {
+        for (; c != null; c = c.getParent()) {
+            if (c instanceof LightweightFrame) {
+                return (LightweightFrame)c;
+            }
+            if (c instanceof Window) {
+                // Don't traverse owner windows
+                return null;
+            }
+        }
+        return null;
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // The following methods help set and identify whether a particular
--- a/jdk/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java	Wed Jul 05 20:00:07 2017 +0200
@@ -187,7 +187,6 @@
     public static native void colorConvert(LCMSTransform trans,
                                            LCMSImageLayout src,
                                            LCMSImageLayout dest);
-    public static native void freeTransform(long ID);
 
     public static native void initLCMS(Class<?> Trans, Class<?> IL, Class<?> Pf);
 
Binary file jdk/src/java.desktop/share/classes/sun/java2d/cmm/profiles/CIEXYZ.pf has changed
Binary file jdk/src/java.desktop/share/classes/sun/java2d/cmm/profiles/GRAY.pf has changed
Binary file jdk/src/java.desktop/share/classes/sun/java2d/cmm/profiles/LINEAR_RGB.pf has changed
Binary file jdk/src/java.desktop/share/classes/sun/java2d/cmm/profiles/PYCC.pf has changed
Binary file jdk/src/java.desktop/share/classes/sun/java2d/cmm/profiles/sRGB.pf has changed
--- a/jdk/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java	Wed Jul 05 20:00:07 2017 +0200
@@ -37,6 +37,13 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Window;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.InvalidDnDOperationException;
+import java.awt.dnd.peer.DragSourceContextPeer;
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
 import java.awt.image.BufferedImage;
@@ -472,4 +479,27 @@
             content.setCursor(target.getCursor());
         }
     }
+
+    public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> abstractRecognizerClass,
+            DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl)
+    {
+        return content == null ? null : content.createDragGestureRecognizer(
+                abstractRecognizerClass, ds, c, srcActions, dgl);
+    }
+
+    public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
+        return content == null ? null : content.createDragSourceContextPeer(dge);
+    }
+
+    public void addDropTarget(DropTarget dt) {
+        if (content == null) return;
+        content.addDropTarget(dt);
+    }
+
+    public void removeDropTarget(DropTarget dt) {
+        if (content == null) return;
+        content.removeDropTarget(dt);
+    }
 }
--- a/jdk/src/java.desktop/share/classes/sun/swing/LightweightContent.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/share/classes/sun/swing/LightweightContent.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,15 @@
 package sun.swing;
 
 import javax.swing.JComponent;
+import java.awt.Component;
 import java.awt.Cursor;
+import java.awt.dnd.DragGestureEvent;
+import java.awt.dnd.DragGestureListener;
+import java.awt.dnd.DragGestureRecognizer;
+import java.awt.dnd.DragSource;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.InvalidDnDOperationException;
+import java.awt.dnd.peer.DragSourceContextPeer;
 
 /**
  * The interface by means of which the {@link JLightweightFrame} class
@@ -209,4 +217,33 @@
      * @param cursor a cursor to set
      */
     default public void setCursor(Cursor cursor) { }
+
+    /**
+     * Create a drag gesture recognizer for the lightweight frame.
+     */
+    default public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
+            Class<T> abstractRecognizerClass,
+            DragSource ds, Component c, int srcActions,
+            DragGestureListener dgl)
+    {
+        return null;
+    }
+
+    /**
+     * Create a drag source context peer for the lightweight frame.
+     */
+    default public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException
+    {
+        return null;
+    }
+
+    /**
+     * Adds a drop target to the lightweight frame.
+     */
+    default public void addDropTarget(DropTarget dt) {}
+
+    /**
+     * Removes a drop target from the lightweight frame.
+     */
+    default public void removeDropTarget(DropTarget dt) {}
 }
Binary file jdk/src/java.desktop/share/conf/cmm/lcms/CIEXYZ.pf has changed
Binary file jdk/src/java.desktop/share/conf/cmm/lcms/GRAY.pf has changed
Binary file jdk/src/java.desktop/share/conf/cmm/lcms/LINEAR_RGB.pf has changed
Binary file jdk/src/java.desktop/share/conf/cmm/lcms/PYCC.pf has changed
Binary file jdk/src/java.desktop/share/conf/cmm/lcms/sRGB.pf has changed
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XLightweightFramePeer.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XLightweightFramePeer.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,6 +26,7 @@
 package sun.awt.X11;
 
 import java.awt.Graphics;
+import java.awt.dnd.DropTarget;
 
 import sun.awt.LightweightFrame;
 import sun.swing.JLightweightFrame;
@@ -69,4 +70,14 @@
     public void updateCursorImmediately() {
         SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
     }
+
+    @Override
+    public void addDropTarget(DropTarget dt) {
+        getLwTarget().addDropTarget(dt);
+    }
+
+    @Override
+    public void removeDropTarget(DropTarget dt) {
+        getLwTarget().removeDropTarget(dt);
+    }
 }
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java	Wed Jul 05 20:00:07 2017 +0200
@@ -927,6 +927,11 @@
     }
 
     public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
+        if (f != null) {
+            return f.createDragSourceContextPeer(dge);
+        }
+
         return XDragSourceContextPeer.createDragSourceContextPeer(dge);
     }
 
@@ -938,6 +943,11 @@
                     int srcActions,
                     DragGestureListener dgl)
     {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(c);
+        if (f != null) {
+            return f.createDragGestureRecognizer(recognizerClass, ds, c, srcActions, dgl);
+        }
+
         if (MouseDragGestureRecognizer.class.equals(recognizerClass))
             return (T)new XMouseDragGestureRecognizer(ds, c, srcActions, dgl);
         else
--- a/jdk/src/java.desktop/unix/native/common/sun/awt/CUPSfuncs.c	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/native/common/sun/awt/CUPSfuncs.c	Wed Jul 05 20:00:07 2017 +0200
@@ -436,6 +436,7 @@
     if (name == NULL) {
         (*env)->ExceptionClear(env);
         JNU_ThrowOutOfMemoryError(env, "Could not create printer name");
+        return;
     }
     const char *filename;
 
@@ -467,8 +468,11 @@
             }
         }
         if (defx > 0) {
-          jobject rxObj = (*env)->NewObject(env, intCls, intCtr, defx);
-          jobject ryObj = (*env)->NewObject(env, intCls, intCtr, defy);
+          jobject rxObj, ryObj;
+          rxObj = (*env)->NewObject(env, intCls, intCtr, defx);
+          CHECK_NULL(rxObj);
+          ryObj = (*env)->NewObject(env, intCls, intCtr, defy);
+          CHECK_NULL(ryObj);
           (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
           (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
         }
@@ -492,8 +496,11 @@
                 }
             }
             if (resx > 0 && (resx != defx || resy != defy )) {
-              jobject rxObj = (*env)->NewObject(env, intCls, intCtr, resx);
-              jobject ryObj = (*env)->NewObject(env, intCls, intCtr, resy);
+              jobject rxObj, ryObj;
+              rxObj = (*env)->NewObject(env, intCls, intCtr, resx);
+              CHECK_NULL(rxObj);
+              ryObj = (*env)->NewObject(env, intCls, intCtr, resy);
+              CHECK_NULL(ryObj);
               (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, rxObj);
               (*env)->CallBooleanMethod(env, arrayList, arrListAddMID, ryObj);
             }
--- a/jdk/src/java.desktop/unix/native/common/sun/awt/X11Color.c	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/native/common/sun/awt/X11Color.c	Wed Jul 05 20:00:07 2017 +0200
@@ -1377,7 +1377,7 @@
 
         /* Unlock now to initialize the SystemColor class */
         if (lock) {
-            AWT_UNLOCK ();
+            AWT_UNLOCK_CHECK_EXCEPTION(env);
         }
         sysColors = (*env)->FindClass (env, "java/awt/SystemColor");
         CHECK_NULL(sysColors);
--- a/jdk/src/java.desktop/unix/native/common/sun/awt/awt.h	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/native/common/sun/awt/awt.h	Wed Jul 05 20:00:07 2017 +0200
@@ -75,6 +75,12 @@
     AWT_NOFLUSH_UNLOCK();                       \
 } while (0)
 
+#define AWT_UNLOCK_CHECK_EXCEPTION(env) \
+    do { \
+      AWT_UNLOCK(); \
+      JNU_CHECK_EXCEPTION(env); \
+    } while (0)
+
 #define AWT_LOCK_IMPL() \
     (*env)->CallStaticVoidMethod(env, tkClass, awtLockMID)
 
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/sun/awt/awt_GraphicsEnv.c	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/sun/awt/awt_GraphicsEnv.c	Wed Jul 05 20:00:07 2017 +0200
@@ -1348,7 +1348,9 @@
     }
 
     /* Make Color Model object for this GraphicsConfiguration */
-    colorModel = awtJNI_GetColorModel (env, adata);
+    colorModel = (*env)->ExceptionCheck(env)
+                 ? NULL : awtJNI_GetColorModel (env, adata);
+
     AWT_UNLOCK ();
 
     return colorModel;
@@ -2052,7 +2054,7 @@
 
     AWT_FLUSH_UNLOCK();
 
-    if (!success) {
+    if (!success && !(*env)->ExceptionCheck(env)) {
         JNU_ThrowInternalError(env, "Could not set display mode");
     }
 #endif /* !HEADLESS */
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/sun/awt/sun_awt_X11_GtkFileDialogPeer.c	Wed Jul 05 20:00:07 2017 +0200
@@ -246,8 +246,14 @@
         }
 
         str = (*env)->NewStringUTF(env, entry);
-        if (str && !(*env)->ExceptionCheck(env)) {
+        if((*env)->ExceptionCheck(env)){
+            break;
+        }
+        if (str) {
             (*env)->SetObjectArrayElement(env, array, i, str);
+            if((*env)->ExceptionCheck(env)){
+                break;
+            }
         }
     }
 
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WLightweightFramePeer.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WLightweightFramePeer.java	Wed Jul 05 20:00:07 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.awt.Component;
 import java.awt.Graphics;
+import java.awt.dnd.DropTarget;
 import java.awt.event.ComponentEvent;
 import java.awt.event.MouseEvent;
 
@@ -94,4 +95,14 @@
     public boolean isLightweightFramePeer() {
         return true;
     }
+
+    @Override
+    public void addDropTarget(DropTarget dt) {
+        getLwTarget().addDropTarget(dt);
+    }
+
+    @Override
+    public void removeDropTarget(DropTarget dt) {
+        getLwTarget().removeDropTarget(dt);
+    }
 }
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java	Wed Jul 05 20:00:07 2017 +0200
@@ -844,6 +844,11 @@
 
     @Override
     public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge) throws InvalidDnDOperationException {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(dge.getComponent());
+        if (f != null) {
+            return f.createDragSourceContextPeer(dge);
+        }
+
         return WDragSourceContextPeer.createDragSourceContextPeer(dge);
     }
 
@@ -854,6 +859,11 @@
                                     DragSource ds, Component c, int srcActions,
                                     DragGestureListener dgl)
     {
+        final LightweightFrame f = SunToolkit.getLightweightFrame(c);
+        if (f != null) {
+            return f.createDragGestureRecognizer(abstractRecognizerClass, ds, c, srcActions, dgl);
+        }
+
         if (MouseDragGestureRecognizer.class.equals(abstractRecognizerClass))
             return (T)new WMouseDragGestureRecognizer(ds, c, srcActions, dgl);
         else
--- a/jdk/src/java.desktop/windows/native/libawt/sun/windows/WPrinterJob.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/sun/windows/WPrinterJob.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, 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
@@ -995,14 +995,7 @@
     if (type == GETJOBCOUNT) {
         ret = pPrinterInfo->cJobs;
     } else if (type == ACCEPTJOB) {
-        if (pPrinterInfo->Status &
-            (PRINTER_STATUS_ERROR |
-             PRINTER_STATUS_NOT_AVAILABLE |
-             PRINTER_STATUS_NO_TONER |
-             PRINTER_STATUS_OUT_OF_MEMORY |
-             PRINTER_STATUS_OFFLINE |
-             PRINTER_STATUS_USER_INTERVENTION |
-             PRINTER_STATUS_DOOR_OPEN)) {
+        if (pPrinterInfo->Status & PRINTER_STATUS_PENDING_DELETION) {
             ret = 0;
         }
         else {
--- a/jdk/src/java.desktop/windows/native/libawt/sun/windows/awt_InputMethod.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/sun/windows/awt_InputMethod.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -482,6 +482,7 @@
         for (current = 0; current < destIndex; current++) {
             if (strcmp(javaLocaleNames[current], srcLocaleName) == 0) {
                 // duplicated. ignore this HKL
+                free((void *)srcLocaleName);
                 break;
             }
         }
--- a/jdk/src/java.desktop/windows/native/libawt/sun/windows/awt_Win32GraphicsDevice.cpp	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/java.desktop/windows/native/libawt/sun/windows/awt_Win32GraphicsDevice.cpp	Wed Jul 05 20:00:07 2017 +0200
@@ -835,13 +835,17 @@
     TRY;
 
     /* class ids */
-    AwtWin32GraphicsDevice::indexCMClass =
-        (jclass)env->NewGlobalRef(env->FindClass("java/awt/image/IndexColorModel"));
+    jclass iCMClass = env->FindClass("java/awt/image/IndexColorModel");
+    CHECK_NULL(iCMClass);
+    AwtWin32GraphicsDevice::indexCMClass = (jclass) env->NewGlobalRef(iCMClass);
+    env->DeleteLocalRef(iCMClass);
     DASSERT(AwtWin32GraphicsDevice::indexCMClass);
     CHECK_NULL(AwtWin32GraphicsDevice::indexCMClass);
 
-    AwtWin32GraphicsDevice::wToolkitClass =
-        (jclass)env->NewGlobalRef(env->FindClass("sun/awt/windows/WToolkit"));
+    jclass wTClass = env->FindClass("sun/awt/windows/WToolkit");
+    CHECK_NULL(wTClass);
+    AwtWin32GraphicsDevice::wToolkitClass = (jclass)env->NewGlobalRef(wTClass);
+    env->DeleteLocalRef(wTClass);
     DASSERT(AwtWin32GraphicsDevice::wToolkitClass);
     CHECK_NULL(AwtWin32GraphicsDevice::wToolkitClass);
 
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/inspector/TableSorter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2014, 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
@@ -146,7 +146,7 @@
         // update row heights in XMBeanAttributes (required by expandable cells)
         if (attrs != null) {
             for (int i = 0; i < getRowCount(); i++) {
-                Vector<?> data = (Vector) dataVector.elementAt(i);
+                Vector<?> data = dataVector.elementAt(i);
                 attrs.updateRowHeight(data.elementAt(1), i);
             }
         }
@@ -217,17 +217,17 @@
             }
     }
 
-    private Vector<Object> getRow(int row) {
+    private Vector<?> getRow(int row) {
         return dataVector.elementAt(row);
     }
 
     @SuppressWarnings("unchecked")
-    private void setRow(Vector<Object> data, int row) {
+    private void setRow(Vector<?> data, int row) {
         dataVector.setElementAt(data,row);
     }
 
     private void swap(int i, int j, int column) {
-        Vector<Object> data = getRow(i);
+        Vector<?> data = getRow(i);
         setRow(getRow(j),i);
         setRow(data,j);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,1 @@
+sun.util.cldr.CLDRLocaleDataMetaInfo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.localedata/META-INF/localedata-services/sun.util.locale.provider.LocaleDataMetaInfo	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,1 @@
+sun.util.resources.provider.NonEnLocaleDataMetaInfo
--- a/jdk/src/jdk.localedata/share/classes/sun/util/resources/lt/CurrencyNames_lt_LT.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/src/jdk.localedata/share/classes/sun/util/resources/lt/CurrencyNames_lt_LT.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -1,5 +1,5 @@
 # 
-# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2014, 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
@@ -35,4 +35,5 @@
 # This notice and attribution to Taligent may not be removed.
 # Taligent is a registered trademark of Taligent, Inc.
 
+EUR=\u20AC
 LTL=Lt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/MiscUndecorated/ActiveAWTWindowTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+* @test
+* @summary To check proper WINDOW_EVENTS are triggered when Frame gains or losses the focus
+* @author Jitender(jitender.singh@eng.sun.com) area=AWT
+* @author yan
+* @library ../../../../lib/testlibrary
+* @build ExtendedRobot
+* @run main ActiveAWTWindowTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class ActiveAWTWindowTest {
+
+    private Frame frame, frame2;
+    private Button button, button2;
+    private TextField textField, textField2;
+    private int eventType, eventType1;
+    private ExtendedRobot robot;
+    private Object lock1 = new Object();
+    private Object lock2 = new Object();
+    private Object lock3 = new Object();
+    private boolean passed = true;
+    private int delay = 150;
+
+    public static void main(String[] args) {
+        ActiveAWTWindowTest test = new ActiveAWTWindowTest();
+        test.doTest();
+    }
+
+    public ActiveAWTWindowTest() {
+        try{
+            EventQueue.invokeAndWait( () -> {
+                    initializeGUI();
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Interrupted or unexpected Exception occured");
+        }
+    }
+
+    private void initializeGUI() {
+        frame = new Frame();
+        frame.setLayout(new FlowLayout());
+
+        frame.setLocation(5, 20);
+        frame.setSize(200, 200);
+        frame.setUndecorated(true);
+        frame.addWindowFocusListener(new WindowFocusListener() {
+            public void windowGainedFocus(WindowEvent event) {
+                System.out.println("Frame Focus gained");
+                synchronized (lock3) {
+                    try {
+                        lock3.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowLostFocus(WindowEvent event) {
+                    System.out.println("Frame Focus lost");
+            }
+        });
+        frame.addWindowListener(new WindowAdapter() {
+            public void windowActivated(WindowEvent e) {
+                eventType = WindowEvent.WINDOW_ACTIVATED;
+                System.out.println("Undecorated Frame is activated\n");
+                synchronized (lock1) {
+                    try {
+                        lock1.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowDeactivated(WindowEvent e) {
+                eventType = WindowEvent.WINDOW_DEACTIVATED;
+                System.out.println("Undecorated Frame got Deactivated\n");
+                synchronized (lock2) {
+                    try {
+                            lock2.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        });
+        textField = new TextField("TextField");
+        button = new Button("Click me");
+        button.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                textField.setText("Focus gained");
+            }
+        });
+
+        frame.setBackground(Color.green);
+        frame.add(button);
+        frame.add(textField);
+        frame.setVisible(true);
+
+        frame2 = new Frame();
+        frame2.setLayout(new FlowLayout());
+        frame2.setLocation(5, 250);
+        frame2.setSize(200, 200);
+        frame2.setBackground(Color.green);
+        button2 = new Button("Click me");
+        textField2 = new TextField("TextField");
+        button2.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                textField2.setText("Got the focus");
+            }
+        });
+
+        frame2.add(button2, BorderLayout.SOUTH);
+        frame2.add(textField2, BorderLayout.NORTH);
+        frame2.setVisible(true);
+
+        frame.toFront();
+    }
+
+    public void doTest() {
+        try {
+            robot = new ExtendedRobot();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Cannot create robot");
+        }
+
+        robot.waitForIdle(5*delay);
+        robot.mouseMove(button.getLocationOnScreen().x + button.getSize().width / 2,
+                        button.getLocationOnScreen().y + button.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        if (eventType != WindowEvent.WINDOW_ACTIVATED) {
+            synchronized (lock1) {
+                try {
+                    lock1.wait(delay * 10);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (eventType != WindowEvent.WINDOW_ACTIVATED) {
+            passed = false;
+            System.err.println("WINDOW_ACTIVATED event did not occur when the " +
+                    "undecorated frame is activated!");
+        }
+
+        eventType1 = -1;
+        eventType = -1;
+
+        robot.mouseMove(button2.getLocationOnScreen().x + button2.getSize().width / 2,
+                        button2.getLocationOnScreen().y + button2.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        if (eventType != WindowEvent.WINDOW_DEACTIVATED) {
+            synchronized (lock2) {
+                try {
+                    lock2.wait(delay * 10);
+                } catch (Exception e) {
+                }
+            }
+        }
+        if (eventType != WindowEvent.WINDOW_DEACTIVATED) {
+            passed = false;
+            System.err.println("FAIL: WINDOW_DEACTIVATED event did not occur for the " +
+                    "undecorated frame when another frame gains focus!");
+        }
+        if (frame.hasFocus()) {
+            passed = false;
+            System.err.println("FAIL: The undecorated frame has focus even when " +
+                        "another frame is clicked!");
+        }
+
+        if (!passed) {
+            //captureScreenAndSave();
+            System.err.println("Test failed!");
+            throw new RuntimeException("Test failed.");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/MiscUndecorated/ActiveSwingWindowTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+* @test
+* @summary To check proper WINDOW_EVENTS are triggered when JFrame gains or losses the focus
+* @author Jitender(jitender.singh@eng.sun.com) area=AWT
+* @author yan
+* @library ../../../../lib/testlibrary
+* @build ExtendedRobot
+* @run main ActiveSwingWindowTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.JFrame;
+import javax.swing.JTextField;
+import javax.swing.JButton;
+
+
+public class ActiveSwingWindowTest {
+
+    private JFrame frame, frame2;
+    private JButton button, button2;
+    private JTextField textField, textField2;
+    private int eventType, eventType1;
+    private ExtendedRobot robot;
+    private Object lock1 = new Object();
+    private Object lock2 = new Object();
+    private Object lock3 = new Object();
+    private boolean passed = true;
+    private int delay = 150;
+
+    public static void main(String[] args) {
+        ActiveSwingWindowTest test = new ActiveSwingWindowTest();
+        test.doTest();
+    }
+
+    public ActiveSwingWindowTest() {
+        try{
+            EventQueue.invokeAndWait( () -> {
+                    initializeGUI();
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Interrupted or unexpected Exception occured");
+        }
+    }
+
+    private void initializeGUI() {
+        frame = new JFrame();
+        frame.setLayout(new FlowLayout());
+
+        frame.setLocation(5, 20);
+        frame.setSize(200, 200);
+        frame.setUndecorated(true);
+        frame.addWindowFocusListener(new WindowFocusListener() {
+            public void windowGainedFocus(WindowEvent event) {
+                System.out.println("Frame Focus gained");
+                synchronized (lock3) {
+                    try {
+                        lock3.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowLostFocus(WindowEvent event) {
+                    System.out.println("Frame Focus lost");
+            }
+        });
+        frame.addWindowListener(new WindowAdapter() {
+            public void windowActivated(WindowEvent e) {
+                eventType = WindowEvent.WINDOW_ACTIVATED;
+                System.out.println("Undecorated Frame is activated\n");
+                synchronized (lock1) {
+                    try {
+                        lock1.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowDeactivated(WindowEvent e) {
+                eventType = WindowEvent.WINDOW_DEACTIVATED;
+                System.out.println("Undecorated Frame got Deactivated\n");
+                synchronized (lock2) {
+                    try {
+                            lock2.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        });
+        textField = new JTextField("TextField");
+        button = new JButton("Click me");
+        button.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                textField.setText("Focus gained");
+            }
+        });
+
+        frame.setBackground(Color.green);
+        frame.add(button);
+        frame.add(textField);
+        frame.setVisible(true);
+
+        frame2 = new JFrame();
+        frame2.setLayout(new FlowLayout());
+        frame2.setLocation(5, 250);
+        frame2.setSize(200, 200);
+        frame2.setBackground(Color.green);
+        button2 = new JButton("Click me");
+        textField2 = new JTextField("TextField");
+        button2.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                textField2.setText("Got the focus");
+            }
+        });
+
+        frame2.add(button2, BorderLayout.SOUTH);
+        frame2.add(textField2, BorderLayout.NORTH);
+        frame2.setVisible(true);
+
+        frame.toFront();
+    }
+
+    public void doTest() {
+        try {
+            robot = new ExtendedRobot();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Cannot create robot");
+        }
+
+        robot.waitForIdle(5*delay);
+        robot.mouseMove(button.getLocationOnScreen().x + button.getSize().width / 2,
+                        button.getLocationOnScreen().y + button.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        if (eventType != WindowEvent.WINDOW_ACTIVATED) {
+            synchronized (lock1) {
+                try {
+                    lock1.wait(delay * 10);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (eventType != WindowEvent.WINDOW_ACTIVATED) {
+            passed = false;
+            System.err.println("WINDOW_ACTIVATED event did not occur when the " +
+                    "undecorated frame is activated!");
+        }
+
+        eventType1 = -1;
+        eventType = -1;
+
+        robot.mouseMove(button2.getLocationOnScreen().x + button2.getSize().width / 2,
+                        button2.getLocationOnScreen().y + button2.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        if (eventType != WindowEvent.WINDOW_DEACTIVATED) {
+            synchronized (lock2) {
+                try {
+                    lock2.wait(delay * 10);
+                } catch (Exception e) {
+                }
+            }
+        }
+        if (eventType != WindowEvent.WINDOW_DEACTIVATED) {
+            passed = false;
+            System.err.println("FAIL: WINDOW_DEACTIVATED event did not occur for the " +
+                    "undecorated frame when another frame gains focus!");
+        }
+        if (frame.hasFocus()) {
+            passed = false;
+            System.err.println("FAIL: The undecorated frame has focus even when " +
+                        "another frame is clicked!");
+        }
+
+        if (!passed) {
+            //captureScreenAndSave();
+            System.err.println("Test failed!");
+            throw new RuntimeException("Test failed.");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/MiscUndecorated/FrameCloseTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+* @test
+* @summary To make sure Undecorated Frame triggers correct windows events while closing
+* @author Jitender(jitender.singh@eng.sun.com) area=AWT*
+* @author yan
+* @library ../../../../lib/testlibrary
+* @build ExtendedRobot
+* @run main FrameCloseTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.JFrame;
+import javax.swing.JButton;
+
+public class FrameCloseTest {
+    private static int delay = 150;
+
+    private Frame frame, frame2;
+    private Component button, dummyButton;
+    private int eventType, eventType1, eventType2;
+    private ExtendedRobot robot;
+    private Object lock1 = new Object();
+    private Object lock2 = new Object();
+    private Object lock3 = new Object();
+    private Object lock4 = new Object();
+    private boolean passed = true;
+
+    public static void main(String[] args) {
+        FrameCloseTest test = new FrameCloseTest();
+        test.doTest(false);
+        test.doTest(true);
+    }
+
+    private void initializeGUI(boolean swingFrame) {
+        frame = swingFrame? new Frame() : new JFrame();
+        frame.setLayout(new FlowLayout());
+
+        frame.setLocation(5, 20);
+        frame.setSize(200, 200);
+        frame.setUndecorated(true);
+        frame.addWindowFocusListener(new WindowFocusListener() {
+            public void windowGainedFocus(WindowEvent event) {
+                System.out.println("Frame Focus gained");
+                synchronized (lock4) {
+                    try {
+                        lock4.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowLostFocus(WindowEvent event) {
+                System.out.println("Frame Focus lost");
+            }
+        });
+        frame.addWindowListener(new WindowAdapter() {
+            public void windowActivated(WindowEvent e) {
+                eventType = WindowEvent.WINDOW_ACTIVATED;
+                System.out.println("Undecorated Frame is activated");
+                synchronized (lock1) {
+                    try {
+                        lock1.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowDeactivated(WindowEvent e) {
+                eventType1 = WindowEvent.WINDOW_DEACTIVATED;
+                System.out.println("Undecorated Frame got Deactivated");
+                synchronized (lock2) {
+                    try {
+                        lock2.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+
+            public void windowClosed(WindowEvent e) {
+                eventType2 = WindowEvent.WINDOW_CLOSED;
+                System.out.println("Undecorated Frame got closed");
+                synchronized (lock3) {
+                    try {
+                        lock3.notifyAll();
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        });
+        dummyButton = swingFrame? new JButton("Click me") : new Button("Click me");
+
+        frame.setBackground(Color.green);
+        frame.add((button = createButton(swingFrame, "Close me")));
+        frame.add(dummyButton);
+        frame.setVisible(true);
+        frame.toFront();
+    }
+    private Component createButton(boolean swingControl, String txt) {
+        if(swingControl) {
+            JButton jbtn = new JButton(txt);
+            jbtn.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    frame.dispose();
+                }
+            });
+            return jbtn;
+        }else {
+            Button btn = new Button(txt);
+            btn.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    frame.dispose();
+                }
+            });
+            return btn;
+        }
+    }
+
+    public void doTest(boolean swingControl) {
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    initializeGUI(swingControl);
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Interrupted or unexpected Exception occured");
+        }
+        try {
+            robot = new ExtendedRobot();
+            robot.waitForIdle(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Cannot create robot");
+        }
+
+        robot.mouseMove(dummyButton.getLocationOnScreen().x + dummyButton.getSize().width / 2,
+                        dummyButton.getLocationOnScreen().y + dummyButton.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+
+        eventType1 = -1;
+        eventType = -1;
+        eventType2 = -1;
+
+        robot.mouseMove(button.getLocationOnScreen().x + button.getSize().width / 2,
+                        button.getLocationOnScreen().y + button.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay * 10);
+
+        if (eventType2 != WindowEvent.WINDOW_CLOSED) {
+            synchronized (lock3) {
+                try {
+                    lock3.wait(delay * 10);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (eventType2 != WindowEvent.WINDOW_CLOSED) {
+            passed = false;
+            System.err.println("WINDOW_CLOSED event did not occur when the " +
+                    "undecorated frame is closed!");
+        }
+        if (eventType == WindowEvent.WINDOW_ACTIVATED) {
+            passed = false;
+            System.err.println("WINDOW_ACTIVATED event occured when the " +
+                    "undecorated frame is closed!");
+        }
+
+        if (!passed) {
+            System.err.println("Test failed!");
+            throw new RuntimeException("Test failed");
+        } else {
+            System.out.println("Test passed");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/MiscUndecorated/RepaintTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+* @test
+* @summary Make sure that on changing state of Undecorated Frame,
+*          all the components on it are repainted correctly
+* @author Jitender(jitender.singh@eng.sun.com) area=AWT
+* @author yan
+* @library ../../../../lib/testlibrary
+* @build ExtendedRobot
+* @run main RepaintTest
+*/
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.JFrame;
+import javax.swing.JButton;
+import javax.swing.JTextField;
+import javax.swing.JPanel;
+import java.io.*;
+import java.awt.image.*;
+
+public class RepaintTest {
+    private static int delay = 150;
+
+    private Frame frame;
+    private Container panel1, panel2;
+    private Component button;
+    private Component textField;
+    private ExtendedRobot robot;
+    private Object buttonLock = new Object();
+    private boolean passed = true;
+    private boolean buttonClicked = false;
+    private int MAX_TOLERANCE_LEVEL = 10;
+
+    public static void main(String[] args) {
+        RepaintTest test = new RepaintTest();
+        test.doTest(false);
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    test.frame.dispose();
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected Exception occured");
+        }
+        test.doTest(true);
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    test.frame.dispose();
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Unexpected Exception occured");
+        }
+    }
+
+    /**
+     * Do screen capture and save it as image
+     */
+    private static void captureScreenAndSave() {
+
+        try {
+            Robot robot = new Robot();
+            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+            Rectangle rectangle = new Rectangle(0, 0, screenSize.width, screenSize.height);
+            System.out.println("About to screen capture - " + rectangle);
+            BufferedImage image = robot.createScreenCapture(rectangle);
+            javax.imageio.ImageIO.write(image, "jpg", new File("ScreenImage.jpg"));
+            robot.delay(3000);
+        } catch (Throwable t) {
+            System.out.println("WARNING: Exception thrown while screen capture!");
+            t.printStackTrace();
+        }
+    }
+
+    private void initializeGUI(boolean swingControl) {
+        frame = swingControl ? new JFrame() : new Frame();
+        frame.setLayout(new BorderLayout());
+
+        frame.setSize(300, 300);
+        frame.setUndecorated(true);
+
+        button = createButton(swingControl, (swingControl ? "Swing Button" : "AWT Button"));
+        textField = swingControl ? new JTextField("TextField") : new TextField("TextField");
+        panel1 = swingControl ? new JPanel() : new Panel();
+        panel2 = swingControl ? new JPanel() : new Panel();
+        panel1.add(button);
+        panel2.add(textField);
+        frame.add(panel2, BorderLayout.SOUTH);
+        frame.add(panel1, BorderLayout.NORTH);
+
+        frame.setBackground(Color.green);
+        frame.setVisible(true);
+        frame.toFront();
+    }
+    private Component createButton(boolean swingControl, String txt) {
+        if(swingControl) {
+            JButton jbtn = new JButton(txt);
+            jbtn.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    buttonClicked = true;
+                    synchronized (buttonLock) {
+                        try {
+                            buttonLock.notifyAll();
+                        } catch (Exception ex) {
+                            ex.printStackTrace();
+                        }
+                    }
+                }
+            });
+            return jbtn;
+        }else {
+            Button btn = new Button(txt);
+            btn.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    buttonClicked = true;
+                    synchronized (buttonLock) {
+                        try {
+                            buttonLock.notifyAll();
+                        } catch (Exception ex) {
+                            ex.printStackTrace();
+                        }
+                    }
+                }
+            });
+            return btn;
+        }
+    }
+
+    public void doTest(boolean swingControl) {
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    initializeGUI(swingControl);
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Interrupted or unexpected Exception occured");
+        }
+        try {
+            robot = new ExtendedRobot();
+            robot.waitForIdle(1000);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Cannot create robot");
+        }
+
+        robot.mouseMove(button.getLocationOnScreen().x + button.getSize().width / 2,
+                        button.getLocationOnScreen().y + button.getSize().height / 2);
+        robot.waitForIdle(delay);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.waitForIdle(delay);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        if (! buttonClicked) {
+            synchronized (buttonLock) {
+                try {
+                    buttonLock.wait(delay * 10);
+                } catch (Exception e) {
+                }
+            }
+        }
+        if (! buttonClicked) {
+            passed = false;
+            System.err.println("ActionEvent not triggered when " +
+                    "button is clicked!");
+            throw new RuntimeException("ActionEvent not triggered");
+        }
+
+        robot.waitForIdle(delay * 5); // Need to wait until look of the button
+                                      // returns to normal undepressed
+        passed = paintAndRepaint(button, (swingControl? "J": "")+"Button");
+        if( !paintAndRepaint(button, (swingControl? "J": "")+"TextField") ) {
+            passed = false;
+        }
+        if(!passed) {
+            throw new RuntimeException("Test failed");
+        }
+    }
+    private boolean paintAndRepaint(Component comp, String prefix) {
+        //Capture the component & compare it's dimensions
+        //before iconifying & after frame comes back from
+        //iconified to normal state
+        System.out.println("paintAndRepaint "+prefix);
+        Point p = comp.getLocationOnScreen();
+        Rectangle bRect = new Rectangle((int)p.getX(), (int)p.getY(),
+                                                comp.getWidth(), comp.getHeight());
+        BufferedImage capturedImage = robot.createScreenCapture(bRect);
+
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setExtendedState(Frame.ICONIFIED);
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Exception while setting extended state ICONIFIED");
+        }
+        robot.waitForIdle(delay * 5);
+        try {
+            Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
+                public void run() {
+                    frame.setExtendedState(Frame.NORMAL);
+                    frame.toFront();
+                }
+            });
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException("Exception while setting extended state NORMAL");
+        }
+        robot.waitForIdle(delay * 5);
+
+        if (! p.equals(comp.getLocationOnScreen())) {
+            passed = false;
+            System.err.println("FAIL: Frame or component did not get positioned in the same place");
+        }
+
+        p = comp.getLocationOnScreen();
+        bRect = new Rectangle((int)p.getX(), (int)p.getY(),
+                                  comp.getWidth(), comp.getHeight());
+        BufferedImage capturedImage2 = robot.createScreenCapture(bRect);
+
+        if (! compareImages(capturedImage, capturedImage2)) {
+            passed = false;
+            try {
+                javax.imageio.ImageIO.write(capturedImage, "jpg", new File(
+                                   prefix+"BeforeMinimize.jpg"));
+                javax.imageio.ImageIO.write(capturedImage2, "jpg", new File(
+                                   prefix+"AfterMinimize.jpg"));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            System.err.println("FAIL: The frame or component did not get repainted correctly");
+        }
+        return passed;
+    }
+
+    //method for comparing two images
+    public boolean compareImages(BufferedImage capturedImg, BufferedImage realImg) {
+        int capturedPixels[], realPixels[];
+        int imgWidth, imgHeight;
+        boolean comparison = true;
+        int toleranceLevel = 0;
+
+        imgWidth = capturedImg.getWidth(null);
+        imgHeight = capturedImg.getHeight(null);
+        capturedPixels = new int[imgWidth * imgHeight];
+        realPixels = new int[imgWidth * imgHeight];
+
+        try {
+            PixelGrabber pgCapturedImg = new PixelGrabber(capturedImg, 0, 0,
+                              imgWidth, imgHeight, capturedPixels, 0, imgWidth);
+            pgCapturedImg.grabPixels();
+
+            PixelGrabber pgRealImg = new PixelGrabber(realImg, 0, 0,
+                              imgWidth, imgHeight, realPixels, 0, imgWidth);
+            pgRealImg.grabPixels();
+
+            for(int i=0; i<(imgWidth * imgHeight); i++) {
+                if(capturedPixels[i] != realPixels[i]) {
+                    toleranceLevel++;
+                }
+            }
+
+            if (toleranceLevel > MAX_TOLERANCE_LEVEL) {
+                comparison = false;
+            }
+        } catch(Exception ie) {
+            ie.printStackTrace();
+            comparison = false;
+        }
+        return comparison;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/MiscUndecorated/UndecoratedInitiallyIconified.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Frame;
+import java.awt.Toolkit;
+import javax.swing.JFrame;
+import java.awt.EventQueue;
+import java.awt.FlowLayout;
+/*
+ * @test
+ * @bug 4464710 7102299
+ * @summary Recurring bug is, an undecorated JFrame cannot be set iconified
+ *          before setVisible(true)
+ *
+ * @run main UndecoratedInitiallyIconified
+ */
+
+
+public class UndecoratedInitiallyIconified {
+    private static JFrame frame;
+    public static void main(String args[]) throws Exception {
+        if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.ICONIFIED)) {
+            return;
+        }
+        EventQueue.invokeAndWait( () -> {
+            frame = new JFrame("Test Frame");
+            frame.setLayout(new FlowLayout());
+            frame.setBounds(50,50,300,300);
+            frame.setUndecorated(true);
+            frame.setExtendedState(Frame.ICONIFIED);
+            if(frame.getExtendedState() != Frame.ICONIFIED) {
+                throw new RuntimeException("getExtendedState is not Frame.ICONIFIED as expected");
+            }
+        });
+    }
+}
--- a/jdk/test/java/awt/Mixing/AWT_Mixing/Util.java	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.awt.Component;
-import java.awt.Frame;
-import java.awt.Dialog;
-import java.awt.Window;
-import java.awt.Button;
-import java.awt.Point;
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.Robot;
-import java.awt.Toolkit;
-import java.awt.IllegalComponentStateException;
-import java.awt.AWTException;
-import java.awt.AWTEvent;
-
-import java.awt.event.InputEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.awt.event.ActionEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.WindowListener;
-import java.awt.event.WindowFocusListener;
-import java.awt.event.FocusListener;
-import java.awt.event.ActionListener;
-
-import java.awt.peer.FramePeer;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * <p>This class contains utilities useful for regression testing.
- * <p>When using jtreg you would include this class into the build
- * list via something like:
- * <pre>
-     &amp;library ../../../../share/lib/AWT_Mixing/src/regtesthelpers/
-     &amp;build Util
-     &amp;run main YourTest
-   </pre>
- * Note that if you are about to create a test based on
- * Applet-template, then put those lines into html-file, not in java-file.
- * <p> And put an
- * import regtesthelpers.Util;
- * into the java source of test.
-*/
-public final class Util {
-    private Util() {} // this is a helper class with static methods :)
-
-    /*
-     * @throws RuntimeException when creation failed
-     */
-    public static Robot createRobot() {
-        try {
-            return new Robot();
-        } catch (AWTException e) {
-            throw new RuntimeException("Error: unable to create robot", e);
-        }
-    }
-
-    public static Frame createEmbeddedFrame(final Frame embedder)
-        throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException,
-               InstantiationException, InvocationTargetException
-    {
-        Toolkit tk = Toolkit.getDefaultToolkit();
-        FramePeer frame_peer = (FramePeer) embedder.getPeer();
-        System.out.println("frame's peer = " + frame_peer);
-        if ("sun.awt.windows.WToolkit".equals(tk.getClass().getName())) {
-            Class comp_peer_class =
-                Class.forName("sun.awt.windows.WComponentPeer");
-            System.out.println("comp peer class = " + comp_peer_class);
-            Field hwnd_field = comp_peer_class.getDeclaredField("hwnd");
-            hwnd_field.setAccessible(true);
-            System.out.println("hwnd_field =" + hwnd_field);
-            long hwnd = hwnd_field.getLong(frame_peer);
-            System.out.println("hwnd = " + hwnd);
-
-            Class clazz = Class.forName("sun.awt.windows.WEmbeddedFrame");
-            Constructor constructor = clazz.getConstructor (new Class [] {Long.TYPE});
-            return (Frame) constructor.newInstance (new Object[] {hwnd});
-        } else if ("sun.awt.X11.XToolkit".equals(tk.getClass().getName())) {
-            Class x_base_window_class = Class.forName("sun.awt.X11.XBaseWindow");
-            System.out.println("x_base_window_class = " + x_base_window_class);
-            Method get_window = x_base_window_class.getMethod("getWindow", new Class[0]);
-            System.out.println("get_window = " + get_window);
-            long window = (Long) get_window.invoke(frame_peer, new Object[0]);
-            System.out.println("window = " + window);
-            Class clazz = Class.forName("sun.awt.X11.XEmbeddedFrame");
-            Constructor constructor = clazz.getConstructor (new Class [] {Long.TYPE, Boolean.TYPE});
-            return (Frame) constructor.newInstance (new Object[] {window, true});
-        }
-
-        throw new RuntimeException("Unexpected toolkit - " + tk);
-    }
-
-    /**
-     * Makes the window visible and waits until it's shown.
-     */
-    public static void showWindowWait(Window win) {
-        win.setVisible(true);
-        waitTillShown(win);
-    }
-
-    /**
-     * Moves mouse pointer in the center of given {@code comp} component
-     * using {@code robot} parameter.
-     */
-    public static void pointOnComp(final Component comp, final Robot robot) {
-        Rectangle bounds = new Rectangle(comp.getLocationOnScreen(), comp.getSize());
-        robot.mouseMove(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
-    }
-
-    /**
-     * Moves mouse pointer in the center of a given {@code comp} component
-     * and performs a left mouse button click using the {@code robot} parameter
-     * with the {@code delay} delay between press and release.
-     */
-    public static void clickOnComp(final Component comp, final Robot robot, int delay) {
-        pointOnComp(comp, robot);
-        robot.delay(delay);
-        robot.mousePress(InputEvent.BUTTON1_MASK);
-        robot.delay(delay);
-        robot.mouseRelease(InputEvent.BUTTON1_MASK);
-    }
-
-    /**
-     * Moves mouse pointer in the center of a given {@code comp} component
-     * and performs a left mouse button click using the {@code robot} parameter
-     * with the default delay between press and release.
-     */
-    public static void clickOnComp(final Component comp, final Robot robot) {
-        clickOnComp(comp, robot, 50);
-    }
-
-    /*
-     * Clicks on a title of Frame/Dialog.
-     * WARNING: it may fail on some platforms when the window is not wide enough.
-     */
-    public static void clickOnTitle(final Window decoratedWindow, final Robot robot) {
-        Point p = decoratedWindow.getLocationOnScreen();
-        Dimension d = decoratedWindow.getSize();
-
-        if (decoratedWindow instanceof Frame || decoratedWindow instanceof Dialog) {
-            robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)decoratedWindow.getInsets().top/2);
-            robot.delay(50);
-            robot.mousePress(InputEvent.BUTTON1_MASK);
-            robot.delay(50);
-            robot.mouseRelease(InputEvent.BUTTON1_MASK);
-        }
-    }
-
-    public static void waitForIdle(final Robot robot) {
-        // we do not use robot for now, use SunToolkit.realSync() instead
-        ((sun.awt.SunToolkit)Toolkit.getDefaultToolkit()).realSync();
-    }
-
-    public static Field getField(final Class klass, final String fieldName) {
-        return AccessController.doPrivileged(new PrivilegedAction<Field>() {
-            public Field run() {
-                try {
-                    Field field = klass.getDeclaredField(fieldName);
-                    assert (field != null);
-                    field.setAccessible(true);
-                    return field;
-                } catch (SecurityException se) {
-                    throw new RuntimeException("Error: unexpected exception caught!", se);
-                } catch (NoSuchFieldException nsfe) {
-                    throw new RuntimeException("Error: unexpected exception caught!", nsfe);
-                }
-            }
-        });
-    }
-
-    /*
-     * Waits for a notification and for a boolean condition to become true.
-     * The method returns when the above conditions are fullfilled or when the timeout
-     * occurs.
-     *
-     * @param condition the object to be notified and the booelan condition to wait for
-     * @param timeout the maximum time to wait in milliseconds
-     * @param catchExceptions if {@code true} the method catches InterruptedException
-     * @return the final boolean value of the {@code condition}
-     * @throws InterruptedException if the awaiting proccess has been interrupted
-     */
-    public static boolean waitForConditionEx(final AtomicBoolean condition, long timeout)
-      throws InterruptedException
-        {
-            synchronized (condition) {
-                long startTime = System.currentTimeMillis();
-                while (!condition.get()) {
-                    condition.wait(timeout);
-                    if (System.currentTimeMillis() - startTime >= timeout ) {
-                        break;
-                    }
-                }
-            }
-            return condition.get();
-        }
-
-    /*
-     * The same as {@code waitForConditionEx(AtomicBoolean, long)} except that it
-     * doesn't throw InterruptedException.
-     */
-    public static boolean waitForCondition(final AtomicBoolean condition, long timeout) {
-        try {
-            return waitForConditionEx(condition, timeout);
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Error: unexpected exception caught!", e);
-        }
-    }
-
-    /*
-     * The same as {@code waitForConditionEx(AtomicBoolean, long)} but without a timeout.
-     */
-    public static void waitForConditionEx(final AtomicBoolean condition)
-      throws InterruptedException
-        {
-            synchronized (condition) {
-                while (!condition.get()) {
-                    condition.wait();
-                }
-            }
-        }
-
-    /*
-     * The same as {@code waitForConditionEx(AtomicBoolean)} except that it
-     * doesn't throw InterruptedException.
-     */
-    public static void waitForCondition(final AtomicBoolean condition) {
-        try {
-            waitForConditionEx(condition);
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Error: unexpected exception caught!", e);
-        }
-    }
-
-    public static void waitTillShownEx(final Component comp) throws InterruptedException {
-        while (true) {
-            try {
-                Thread.sleep(100);
-                comp.getLocationOnScreen();
-                break;
-            } catch (IllegalComponentStateException e) {}
-        }
-    }
-    public static void waitTillShown(final Component comp) {
-        try {
-            waitTillShownEx(comp);
-        } catch (InterruptedException e) {
-            throw new RuntimeException("Error: unexpected exception caught!", e);
-        }
-    }
-
-    /**
-     * Drags from one point to another with the specified mouse button pressed.
-     *
-     * @param robot a robot to use for moving the mouse, etc.
-     * @param startPoint a start point of the drag
-     * @param endPoint an end point of the drag
-     * @param button one of {@code InputEvent.BUTTON1_MASK},
-     *     {@code InputEvent.BUTTON2_MASK}, {@code InputEvent.BUTTON3_MASK}
-     *
-     * @throws IllegalArgumentException if {@code button} is not one of
-     *     {@code InputEvent.BUTTON1_MASK}, {@code InputEvent.BUTTON2_MASK},
-     *     {@code InputEvent.BUTTON3_MASK}
-     */
-    public static void drag(Robot robot, Point startPoint, Point endPoint, int button) {
-        if (!(button == InputEvent.BUTTON1_MASK || button == InputEvent.BUTTON2_MASK
-                || button == InputEvent.BUTTON3_MASK))
-        {
-            throw new IllegalArgumentException("invalid mouse button");
-        }
-
-        robot.mouseMove(startPoint.x, startPoint.y);
-        robot.mousePress(button);
-        try {
-            mouseMove(robot, startPoint, endPoint);
-        } finally {
-            robot.mouseRelease(button);
-        }
-    }
-
-    /**
-     * Moves the mouse pointer from one point to another.
-     * Uses Bresenham's algorithm.
-     *
-     * @param robot a robot to use for moving the mouse
-     * @param startPoint a start point of the drag
-     * @param endPoint an end point of the drag
-     */
-    public static void mouseMove(Robot robot, Point startPoint, Point endPoint) {
-        int dx = endPoint.x - startPoint.x;
-        int dy = endPoint.y - startPoint.y;
-
-        int ax = Math.abs(dx) * 2;
-        int ay = Math.abs(dy) * 2;
-
-        int sx = signWOZero(dx);
-        int sy = signWOZero(dy);
-
-        int x = startPoint.x;
-        int y = startPoint.y;
-
-        int d = 0;
-
-        if (ax > ay) {
-            d = ay - ax/2;
-            while (true){
-                robot.mouseMove(x, y);
-                robot.delay(50);
-
-                if (x == endPoint.x){
-                    return;
-                }
-                if (d >= 0){
-                    y = y + sy;
-                    d = d - ax;
-                }
-                x = x + sx;
-                d = d + ay;
-            }
-        } else {
-            d = ax - ay/2;
-            while (true){
-                robot.mouseMove(x, y);
-                robot.delay(50);
-
-                if (y == endPoint.y){
-                    return;
-                }
-                if (d >= 0){
-                    x = x + sx;
-                    d = d - ay;
-                }
-                y = y + sy;
-                d = d + ax;
-            }
-        }
-    }
-
-    private static int signWOZero(int i){
-        return (i > 0)? 1: -1;
-    }
-
-    private static int sign(int n) {
-        return n < 0 ? -1 : n == 0 ? 0 : 1;
-    }
-
-    /** Returns {@code WindowListener} instance that diposes {@code Window} on
-     *  "window closing" event.
-     *
-     * @return    the {@code WindowListener} instance that could be set
-     *            on a {@code Window}. After that
-     *            the {@code Window} is disposed when "window closed"
-     *            event is sent to the {@code Window}
-     */
-    public static WindowListener getClosingWindowAdapter() {
-        return new WindowAdapter () {
-            public void windowClosing(WindowEvent e) {
-                e.getWindow().dispose();
-            }
-        };
-    }
-
-    /*
-     * The values directly map to the ones of
-     * sun.awt.X11.XWM & sun.awt.motif.MToolkit classes.
-     */
-    public final static int
-        UNDETERMINED_WM = 1,
-        NO_WM = 2,
-        OTHER_WM = 3,
-        OPENLOOK_WM = 4,
-        MOTIF_WM = 5,
-        CDE_WM = 6,
-        ENLIGHTEN_WM = 7,
-        KDE2_WM = 8,
-        SAWFISH_WM = 9,
-        ICE_WM = 10,
-        METACITY_WM = 11,
-        COMPIZ_WM = 12,
-        LG3D_WM = 13;
-
-    /*
-     * Returns -1 in case of not X Window or any problems.
-     */
-    public static int getWMID() {
-        Class clazz = null;
-        try {
-            if ("sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
-                clazz = Class.forName("sun.awt.X11.XWM");
-            } else if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
-                clazz = Class.forName("sun.awt.motif.MToolkit");
-            }
-        } catch (ClassNotFoundException cnfe) {
-            cnfe.printStackTrace();
-        }
-        if (clazz == null) {
-            return -1;
-        }
-
-        try {
-            final Class _clazz = clazz;
-            Method m_getWMID = (Method)AccessController.doPrivileged(new PrivilegedAction() {
-                    public Object run() {
-                        try {
-                            Method method = _clazz.getDeclaredMethod("getWMID", new Class[] {});
-                            if (method != null) {
-                                method.setAccessible(true);
-                            }
-                            return method;
-                        } catch (NoSuchMethodException e) {
-                            assert false;
-                        } catch (SecurityException e) {
-                            assert false;
-                        }
-                        return null;
-                    }
-                });
-            return ((Integer)m_getWMID.invoke(null, new Object[] {})).intValue();
-        } catch (IllegalAccessException iae) {
-            iae.printStackTrace();
-        } catch (InvocationTargetException ite) {
-            ite.printStackTrace();
-        }
-        return -1;
-    }
-
-
-    ////////////////////////////
-    // Some stuff to test focus.
-    ////////////////////////////
-
-    private static WindowGainedFocusListener wgfListener = new WindowGainedFocusListener();
-    private static FocusGainedListener fgListener = new FocusGainedListener();
-    private static ActionPerformedListener apListener = new ActionPerformedListener();
-
-    private abstract static class EventListener {
-        AtomicBoolean notifier = new AtomicBoolean(false);
-        Component comp;
-        boolean printEvent;
-
-        public void listen(Component comp, boolean printEvent) {
-            this.comp = comp;
-            this.printEvent = printEvent;
-            notifier.set(false);
-            setListener(comp);
-        }
-
-        public AtomicBoolean getNotifier() {
-            return notifier;
-        }
-
-        abstract void setListener(Component comp);
-
-        void printAndNotify(AWTEvent e) {
-            if (printEvent) {
-                System.err.println(e);
-            }
-            synchronized (notifier) {
-                notifier.set(true);
-                notifier.notifyAll();
-            }
-        }
-    }
-
-    private static class WindowGainedFocusListener extends EventListener implements WindowFocusListener {
-
-        void setListener(Component comp) {
-            ((Window)comp).addWindowFocusListener(this);
-        }
-
-        public void windowGainedFocus(WindowEvent e) {
-
-            ((Window)comp).removeWindowFocusListener(this);
-            printAndNotify(e);
-        }
-
-        public void windowLostFocus(WindowEvent e) {}
-    }
-
-    private static class FocusGainedListener extends EventListener implements FocusListener {
-
-        void setListener(Component comp) {
-            comp.addFocusListener(this);
-        }
-
-        public void focusGained(FocusEvent e) {
-            comp.removeFocusListener(this);
-            printAndNotify(e);
-        }
-
-        public void focusLost(FocusEvent e) {}
-    }
-
-    private static class ActionPerformedListener extends EventListener implements ActionListener {
-
-        void setListener(Component comp) {
-            ((Button)comp).addActionListener(this);
-        }
-
-        public void actionPerformed(ActionEvent e) {
-            ((Button)comp).removeActionListener(this);
-            printAndNotify(e);
-        }
-    }
-
-    private static boolean trackEvent(int eventID, Component comp, Runnable action, int time, boolean printEvent) {
-        EventListener listener = null;
-
-        switch (eventID) {
-        case WindowEvent.WINDOW_GAINED_FOCUS:
-            listener = wgfListener;
-            break;
-        case FocusEvent.FOCUS_GAINED:
-            listener = fgListener;
-            break;
-        case ActionEvent.ACTION_PERFORMED:
-            listener = apListener;
-            break;
-        }
-
-        listener.listen(comp, printEvent);
-        action.run();
-        return Util.waitForCondition(listener.getNotifier(), time);
-    }
-
-    /*
-     * Tracks WINDOW_GAINED_FOCUS event for a window caused by an action.
-     * @param window the window to track the event for
-     * @param action the action to perform
-     * @param time the max time to wait for the event
-     * @param printEvent should the event received be printed or doesn't
-     * @return true if the event has been received, otherwise false
-     */
-    public static boolean trackWindowGainedFocus(Window window, Runnable action, int time, boolean printEvent) {
-        return trackEvent(WindowEvent.WINDOW_GAINED_FOCUS, window, action, time, printEvent);
-    }
-
-    /*
-     * Tracks FOCUS_GAINED event for a component caused by an action.
-     * @see #trackWindowGainedFocus
-     */
-    public static boolean trackFocusGained(Component comp, Runnable action, int time, boolean printEvent) {
-        return trackEvent(FocusEvent.FOCUS_GAINED, comp, action, time, printEvent);
-    }
-
-    /*
-     * Tracks ACTION_PERFORMED event for a button caused by an action.
-     * @see #trackWindowGainedFocus
-     */
-    public static boolean trackActionPerformed(Button button, Runnable action, int time, boolean printEvent) {
-        return trackEvent(ActionEvent.ACTION_PERFORMED, button, action, time, printEvent);
-    }
-
-    /*
-     * Requests focus on the component provided and waits for the result.
-     * @return true if the component has been focused, false otherwise.
-     */
-    public static boolean focusComponent(Component comp, int time) {
-        return focusComponent(comp, time, false);
-    }
-    public static boolean focusComponent(final Component comp, int time, boolean printEvent) {
-        return trackFocusGained(comp,
-                                new Runnable() {
-                                    public void run() {
-                                        comp.requestFocus();
-                                    }
-                                },
-                                time, printEvent);
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/color/LoadStandardProfilesTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014, 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 8039271
+ * @summary test all standard profiles load correctly.
+ */
+
+import java.awt.color.ICC_Profile;
+
+public class LoadStandardProfilesTest {
+
+    public static void main(String args[]) {
+        try {
+            ICC_Profile sRGB      = ICC_Profile.getInstance("sRGB.pf");
+            ICC_Profile gray      = ICC_Profile.getInstance("GRAY.pf");
+            ICC_Profile pycc      = ICC_Profile.getInstance("PYCC.pf");
+            ICC_Profile ciexyz    = ICC_Profile.getInstance("CIEXYZ.pf");
+            ICC_Profile linearRGB = ICC_Profile.getInstance("LINEAR_RGB.pf");
+
+            if (sRGB == null ||
+                gray == null ||
+                pycc == null ||
+                ciexyz == null ||
+                linearRGB == null)
+            {
+                throw new RuntimeException("null profile.");
+            }
+        } catch (Exception e) {
+           throw new RuntimeException(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/DoPrivAccomplice.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class DoPrivAccomplice {
+
+    public String go() {
+        String name = (String)java.security.AccessController.
+                doPrivileged((java.security.PrivilegedAction)() ->
+                        System.getProperty("user.name"));
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/DoPrivAccompliceTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @test
+ * @bug 8048362
+ * @compile ../../../lib/testlibrary/JavaToolUtils.java
+ *                             DoPrivAccomplice.java DoPrivTest.java
+ * @summary Tests the doPrivileged with accomplice Generate two jars
+ * (DoPrivTest.jar and DoPrivAccomplice.jar) and grant permission to
+ * DoPrivAccmplice.jar for reading user.home property from a PrivilagedAction.
+ * Run DoPrivTest.jar and try to access user.home property using
+ * DoPrivAccmplice.jar.
+ * @run main/othervm DoPrivAccompliceTest
+ */
+
+public class DoPrivAccompliceTest {
+
+    private static final String PWD = System.getProperty("test.classes", "./");
+    private static final String ACTION_SOURCE = "DoPrivAccomplice";
+    private static final String TEST_SOURCE = "DoPrivTest";
+
+    public static void createPolicyFile(URI codebaseURL) throws IOException {
+        String codebase = codebaseURL.toString();
+        String quotes = "\"";
+        StringBuilder policyFile = new StringBuilder();
+        policyFile.append("grant codeBase ").append(quotes).
+                append(codebase).append(quotes).append("{\n").
+                append("permission java.util.PropertyPermission ").
+                append(quotes).append("user.name").append(quotes).
+                append(",").append(quotes).append("read").append(quotes).
+                append(";\n};");
+        try (FileWriter writer = new FileWriter(new File(PWD, "java.policy"))) {
+            writer.write(policyFile.toString());
+            writer.close();
+        } catch (IOException e) {
+            System.err.println("Error while creating policy file");
+            throw e;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        final File class1 = new File(PWD, ACTION_SOURCE + ".class");
+        final File class2 = new File(PWD, TEST_SOURCE + ".class");
+        final File jarFile1 = new File(PWD, ACTION_SOURCE + ".jar");
+        final File jarFile2 = new File(PWD, TEST_SOURCE + ".jar");
+        System.out.println("Compilation successfull");
+        JavaToolUtils.createJar(jarFile1, Arrays.asList(new File[]{class1}));
+        System.out.println("Created jar file " + jarFile1);
+        JavaToolUtils.createJar(jarFile2, Arrays.asList(new File[]{class2}));
+        System.out.println("Created jar file " + jarFile2);
+        createPolicyFile(jarFile1.toURI());
+
+        List<String> commands = new ArrayList<>();
+        final String pathSepartor = System.getProperty("path.separator");
+        commands.add("-Djava.security.manager");
+        commands.add("-Djava.security.policy=" + PWD + "/java.policy");
+        commands.add("-classpath");
+        commands.add(PWD + "/" + TEST_SOURCE + ".jar" + pathSepartor
+                + PWD + "/" + ACTION_SOURCE + ".jar");
+        commands.add(TEST_SOURCE);
+        if (JavaToolUtils.runJava(commands) == 0) {
+            System.out.println("Test PASSES");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/AccessController/DoPrivTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class DoPrivTest {
+
+    public static void main(String[] args) {
+        String name = new DoPrivAccomplice().go();
+        System.out.println("Received Name : " + name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/KeyStore/TestKeyStoreBasic.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2001, 2014, 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 static java.lang.System.out;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/*
+ * @test
+ * @bug 8048621
+ * @summary Test the basic operations of KeyStore, provided by SunJCE (jceks),
+ *  and SunPKCS11-Solaris(PKCS11KeyStore)
+ * @author Yu-Ching Valerie PENG
+ */
+
+public class TestKeyStoreBasic {
+    private static final char[] PASSWD2 = new char[] {
+            'b', 'o', 'r', 'e', 'd'
+    };
+    private static final char[] PASSWDK = new String("cannot be null")
+            .toCharArray();
+    private static final String[] KS_Type = {
+            "jks", "jceks", "pkcs12", "PKCS11KeyStore"
+    };
+    private static final String[] PRO_TYPE = {
+            "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris"
+    };
+    private static final String ALIAS_HEAD = "test";
+
+    public static void main(String args[]) throws Exception {
+        TestKeyStoreBasic jstest = new TestKeyStoreBasic();
+        jstest.run();
+    }
+
+    public void run() throws Exception {
+        Provider[] providers = Security.getProviders();
+        for (Provider p: providers) {
+            String prvName = p.getName();
+            if (prvName.startsWith("SunJCE")
+                    || prvName.startsWith("SunPKCS11-Solaris")) {
+                try {
+                    runTest(p);
+                    out.println("Test with provider " + p.getName() + ""
+                            + " passed");
+                } catch (java.security.KeyStoreException e) {
+                    if (prvName.startsWith("SunPKCS11-Solaris")) {
+                        out.println("KeyStoreException is expected "
+                                + "PKCS11KeyStore is invalid keystore type.");
+                        e.printStackTrace();
+                    } else {
+                        throw e;
+                    }
+                }
+            }
+        }
+    }
+
+    public void runTest(Provider p) throws Exception {
+        SecretKey key = new SecretKeySpec(
+                new String("No one knows").getBytes(), "PBE");
+        int numEntries = 5;
+        String proName = p.getName();
+        String type = null;
+        for (int i = 0; i < PRO_TYPE.length; i++) {
+            if (proName.compareTo(PRO_TYPE[i]) == 0) {
+                type = KS_Type[i];
+                break;
+            }
+        }
+        KeyStore ks = KeyStore.getInstance(type, p);
+        KeyStore ks2 = KeyStore.getInstance(type, ks.getProvider().getName());
+
+        // create an empty key store
+        ks.load(null, null);
+
+        // store the secret keys
+        for (int j = 0; j < numEntries; j++) {
+            ks.setKeyEntry(ALIAS_HEAD + j, key, PASSWDK, null);
+        }
+
+        // initialize the 2nd key store object with the 1st one
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ks.store(baos, PASSWDK);
+        byte[] bArr = baos.toByteArray();
+        ByteArrayInputStream bais = new ByteArrayInputStream(bArr);
+        ks2.load(bais, null);
+
+        // check 2nd key store type
+        checkType(ks2, type);
+        // check the existing aliases for the 2nd key store
+        checkAlias(ks2, numEntries);
+
+        // compare the creation date of the 2 key stores for all aliases
+        compareCreationDate(ks, ks2, numEntries);
+        // remove the last entry from the 2nd key store
+        numEntries--;
+        ks2.deleteEntry(ALIAS_HEAD + numEntries);
+
+        // re-initialize the 1st key store with the 2nd key store
+        baos.reset();
+        ks2.store(baos, PASSWD2);
+        bais = new ByteArrayInputStream(baos.toByteArray());
+        try {
+            // expect an exception since the password is incorrect
+            ks.load(bais, PASSWDK);
+            throw new RuntimeException(
+                    "ERROR: passed the loading with incorrect password");
+        } catch (IOException ex) {
+            bais.reset();
+            ks.load(bais, PASSWD2);
+            bais.reset();
+            ks.load(bais, null);
+        } finally {
+            bais.close();
+            baos.close();
+        }
+
+        // check key store type
+        checkType(ks, type);
+
+        // check the existing aliases
+        checkAlias(ks, numEntries);
+
+        // compare the creation date of the 2 key stores for all aliases
+        compareCreationDate(ks, ks2, numEntries);
+
+    }
+
+    // check key store type
+    private void checkType(KeyStore obj, String type) {
+        if (!obj.getType().equals(type)) {
+            throw new RuntimeException("ERROR: wrong key store type");
+
+        }
+    }
+
+    // check the existing aliases
+    private void checkAlias(KeyStore obj, int range) throws KeyStoreException {
+        for (int k = 0; k < range; k++) {
+            if (!obj.containsAlias(ALIAS_HEAD + k)) {
+                throw new RuntimeException("ERROR: alias (" + k
+                        + ") should exist");
+
+            }
+        }
+    }
+
+    // compare the creation dates - true if all the same
+    private void compareCreationDate(KeyStore o1, KeyStore o2, int range)
+            throws KeyStoreException {
+        boolean result = true;
+        String alias = null;
+        for (int k = 0; k < range; k++) {
+            alias = ALIAS_HEAD + k;
+            if (!o1.getCreationDate(alias).equals(o2.getCreationDate(alias))) {
+                throw new RuntimeException("ERROR: entry creation time (" + k
+                        + ") differs");
+
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/KeyStore/TestKeyStoreEntry.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001, 2014, 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 static java.lang.System.out;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+/*
+ * @test
+ * @bug 8048621
+ * @summary Test the basic operations of KeyStore entry, provided by SunJCE
+ *  (jceks), and SunPKCS11-Solaris(PKCS11KeyStore)
+ * @author Yu-Ching Valerie PENG
+ */
+
+public class TestKeyStoreEntry {
+    private static final char[] PASSWDK = new char[] {
+            't', 'e', 'r', 'c', 'e', 's'
+    };
+    private static final char[] PASSWDF = new String("guardian Angel")
+            .toCharArray();
+    private static final String[] KS_ALGOS = {
+            "DES", "DESede", "Blowfish"
+    };
+    private static final int NUM_ALGOS = KS_ALGOS.length;
+
+    private static final String[] KS_TYPE = {
+            "jks", "jceks", "pkcs12", "PKCS11KeyStore"
+    };
+    private static final String[] PRO_TYPE = {
+            "SUN", "SunJCE", "SunJSSE", "SunPKCS11-Solaris"
+    };
+
+    private final SecretKey[] sks = new SecretKey[NUM_ALGOS];
+
+    TestKeyStoreEntry() throws Exception {
+        // generate secret keys which are to be stored in the jce
+        // key store object
+        KeyGenerator[] kgs = new KeyGenerator[NUM_ALGOS];
+        for (int i = 0; i < NUM_ALGOS; i++) {
+            kgs[i] = KeyGenerator.getInstance(KS_ALGOS[i], "SunJCE");
+            sks[i] = kgs[i].generateKey();
+        }
+
+    }
+
+    public static void main(String args[]) throws Exception {
+        TestKeyStoreEntry jstest = new TestKeyStoreEntry();
+        jstest.run();
+    }
+
+    public void run() throws Exception {
+
+        Provider[] providers = Security.getProviders();
+        for (Provider p: providers) {
+            String prvName = p.getName();
+            if (prvName.startsWith("SunJCE")
+                    || prvName.startsWith("SunPKCS11-Solaris")) {
+                try {
+                    runTest(p);
+                    out.println("Test with provider " + p.getName() + ""
+                            + " passed");
+
+                } catch (java.security.KeyStoreException e) {
+                    if (prvName.startsWith("SunPKCS11-Solaris")) {
+                        out.println("KeyStoreException is expected because "
+                                + "PKCS11KeyStore is invalid keystore type.");
+                        e.printStackTrace();
+                    } else {
+                        throw e;
+                    }
+                }
+            }
+        }
+    }
+
+    public void runTest(Provider p) throws Exception {
+        try (FileOutputStream fos = new FileOutputStream("jceks");
+                FileInputStream fis = new FileInputStream("jceks");) {
+
+            KeyStore ks = KeyStore.getInstance("jceks", p);
+            // create an empty key store
+            ks.load(null, null);
+
+            // store the secret keys
+            String aliasHead = new String("secretKey");
+            for (int j = 0; j < NUM_ALGOS; j++) {
+                ks.setKeyEntry(aliasHead + j, sks[j], PASSWDK, null);
+            }
+
+            // write the key store out to a file
+            ks.store(fos, PASSWDF);
+            // wipe clean the existing key store
+            for (int k = 0; k < NUM_ALGOS; k++) {
+                ks.deleteEntry(aliasHead + k);
+            }
+            if (ks.size() != 0) {
+                throw new RuntimeException("ERROR: re-initialization failed");
+            }
+
+            // reload the key store with the file
+            ks.load(fis, PASSWDF);
+
+            // check the integrity/validaty of the key store
+            Key temp = null;
+            String alias = null;
+            if (ks.size() != NUM_ALGOS) {
+                throw new RuntimeException("ERROR: wrong number of key"
+                        + " entries");
+            }
+
+            for (int m = 0; m < ks.size(); m++) {
+                alias = aliasHead + m;
+                temp = ks.getKey(alias, PASSWDK);
+                // compare the keys
+                if (!temp.equals(sks[m])) {
+                    throw new RuntimeException("ERROR: key comparison (" + m
+                            + ") failed");
+                }
+                // check the type of key
+                if (ks.isCertificateEntry(alias) || !ks.isKeyEntry(alias)) {
+                    throw new RuntimeException("ERROR: type identification ("
+                            + m + ") failed");
+                }
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/sql/test/sql/DriverManagerPermissionsTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.sql;
+
+import java.security.AccessControlException;
+import java.security.Policy;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.StubDriver;
+import util.TestPolicy;
+
+public class DriverManagerPermissionsTests extends BaseTest {
+
+    private  static Policy policy;
+    private static SecurityManager sm;
+
+    /*
+     * Install a SecurityManager along with a base Policy to allow testNG to run
+     */
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        setPolicy(new TestPolicy());
+        System.setSecurityManager(new SecurityManager());
+    }
+
+    /*
+     * Install the original Policy and SecurityManager
+     */
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        System.setSecurityManager(sm);
+        setPolicy(policy);
+    }
+
+    /*
+     * Save off the original Policy and SecurityManager
+     */
+    public DriverManagerPermissionsTests() {
+        policy = Policy.getPolicy();
+        sm = System.getSecurityManager();
+    }
+
+    /*
+     * Validate that AccessControlException is thrown if SQLPermission("setLog")
+     * has not been granted
+     */
+    @Test(expectedExceptions = AccessControlException.class)
+    public void test() {
+        setPolicy(new TestPolicy());
+        DriverManager.setLogStream(null);
+    }
+
+    /*
+     * Validate that setLogStream succeeds if SQLPermission("setLog") has been
+     * granted
+     */
+    @Test
+    public void test1() {
+        Policy.setPolicy(new TestPolicy("setLog"));
+        DriverManager.setLogStream(null);
+    }
+
+    /*
+     * Validate that setLogStream succeeds if AllPermissions has been granted
+     */
+    @Test
+    public void test2() {
+        setPolicy(new TestPolicy("all"));
+        DriverManager.setLogStream(null);
+    }
+
+    /*
+     * Validate that AccessControlException is thrown if SQLPermission("setLog")
+     * has not been granted
+     */
+    @Test(expectedExceptions = AccessControlException.class)
+    public void test4() {
+        setPolicy(new TestPolicy());
+        DriverManager.setLogWriter(null);
+    }
+
+    /*
+     * Validate that setLogWriter succeeds if SQLPermission("setLog") has been
+     * granted
+     */
+    @Test
+    public void test5() {
+        setPolicy(new TestPolicy("setLog"));
+        DriverManager.setLogWriter(null);
+    }
+
+    /*
+     * Validate that setLogWriter succeeds if AllPermissions has been granted
+     */
+    @Test
+    public void test6() {
+        setPolicy(new TestPolicy("all"));
+        DriverManager.setLogWriter(null);
+    }
+
+    /*
+     * Validate that AccessControlException is thrown if
+     * SQLPermission("deregisterDriver") has not been granted
+     */
+    @Test(expectedExceptions = AccessControlException.class)
+    public void test7() throws SQLException {
+        setPolicy(new TestPolicy());
+        DriverManager.deregisterDriver(new StubDriver());
+    }
+
+    /*
+     * Validate that deregisterDriver succeeds if
+     * SQLPermission("deregisterDriver") has been granted
+     */
+    @Test
+    public void test8() throws SQLException {
+        setPolicy(new TestPolicy("deregisterDriver"));
+        DriverManager.deregisterDriver(new StubDriver());
+    }
+
+    /*
+     * Validate that deregisterDriver succeeds if AllPermissions has been
+     * granted
+     */
+    @Test
+    public void test9() throws SQLException {
+        setPolicy(new TestPolicy("all"));
+        DriverManager.deregisterDriver(new StubDriver());
+    }
+}
--- a/jdk/test/java/sql/util/BaseTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/java/sql/util/BaseTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -27,6 +27,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.security.Policy;
 import java.sql.SQLException;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
@@ -88,4 +89,11 @@
         }
         return o1;
     }
+
+    /*
+     * Utility Method used to set the current Policy
+     */
+    protected static void setPolicy(Policy p) {
+        Policy.setPolicy(p);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/sql/util/TestPolicy.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.FilePermission;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+import java.sql.SQLPermission;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+import java.util.StringJoiner;
+
+/*
+ * Simple Policy class that supports the required Permissions to validate the
+ * JDBC concrete classes
+ */
+public class TestPolicy extends Policy {
+
+    final PermissionCollection permissions = new Permissions();
+
+    /**
+     * Constructor which sets the minimum permissions allowing testNG to work
+     * with a SecurityManager
+     */
+    public TestPolicy() {
+        setMinimalPermissions();
+    }
+
+    /*
+     * Constructor which determines which permissions are defined for this
+     * Policy used by the JDBC tests Possible values are: all (ALLPermissions),
+     * setLog (SQLPemission("setLog"), deregisterDriver
+     * (SQLPermission("deregisterDriver") (SQLPermission("deregisterDriver"),
+     * and setSyncFactory(SQLPermission(setSyncFactory),
+     *
+     * @param policy Permissions to set
+     */
+    public TestPolicy(String policy) {
+
+        switch (policy) {
+            case "all":
+                permissions.add(new AllPermission());
+                break;
+            case "setLog":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("setLog"));
+                break;
+            case "deregisterDriver":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("deregisterDriver"));
+                break;
+            case "setSyncFactory":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("setSyncFactory"));
+                break;
+            default:
+                setMinimalPermissions();
+        }
+    }
+
+    /*
+     * Defines the minimal permissions required by testNG when running these
+     * tests
+     */
+    private void setMinimalPermissions() {
+        permissions.add(new SecurityPermission("getPolicy"));
+        permissions.add(new SecurityPermission("setPolicy"));
+        permissions.add(new RuntimePermission("getClassLoader"));
+        permissions.add(new RuntimePermission("setSecurityManager"));
+        permissions.add(new RuntimePermission("createSecurityManager"));
+        permissions.add(new PropertyPermission("testng.show.stack.frames",
+                "read"));
+        permissions.add(new PropertyPermission("line.separator", "read"));
+        permissions.add(new PropertyPermission("fileStringBuffer", "read"));
+        permissions.add(new PropertyPermission("dataproviderthreadcount", "read"));
+        permissions.add(new PropertyPermission("java.io.tmpdir", "read"));
+        permissions.add(new FilePermission("<<ALL FILES>>",
+                "read, write, delete"));
+    }
+
+    /*
+     * Overloaded methods from the Policy class
+     */
+    @Override
+    public String toString() {
+        StringJoiner sj = new StringJoiner("\n", "policy: ", "");
+        Enumeration<Permission> perms = permissions.elements();
+        while (perms.hasMoreElements()) {
+            sj.add(perms.nextElement().toString());
+        }
+        return sj.toString();
+
+    }
+
+    @Override
+    public PermissionCollection getPermissions(ProtectionDomain domain) {
+        return permissions;
+    }
+
+    @Override
+    public PermissionCollection getPermissions(CodeSource codesource) {
+        return permissions;
+    }
+
+    @Override
+    public boolean implies(ProtectionDomain domain, Permission perm) {
+        return permissions.implies(perm);
+    }
+}
--- a/jdk/test/java/util/Currency/tablea1.txt	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/java/util/Currency/tablea1.txt	Wed Jul 05 20:00:07 2017 +0200
@@ -1,12 +1,12 @@
 #
 #
-# Amendments up until ISO 4217 AMENDMENT NUMBER 156
-#   (As of 23 July 2013)
+# Amendments up until ISO 4217 AMENDMENT NUMBER 159
+#   (As of 15 August 2014)
 #
 
 # Version
 FILEVERSION=1
-DATAVERSION=156
+DATAVERSION=159
 
 # ISO 4217 currency data
 AF	AFN	971	2
@@ -142,7 +142,7 @@
 LR	LRD	430	2
 LY	LYD	434	3
 LI	CHF	756	2
-LT	LTL	440	2
+LT	LTL	440	2	2014-12-31-22-00-00	EUR	978	2
 LU	EUR	978	2
 MO	MOP	446	2
 MK	MKD	807	2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/CipherTestUtils.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,687 @@
+/**
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 only, as published by
+ * the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more
+ * details (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version 2
+ * along with this work; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or
+ * visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.List;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Test that all ciphersuites work in all versions and all client authentication
+ * types. The way this is setup the server is stateless and all checking is done
+ * on the client side.
+ */
+
+public class CipherTestUtils {
+
+    public static final int TIMEOUT = 20 * 1000;
+    public static final SecureRandom secureRandom = new SecureRandom();
+    public static char[] PASSWORD = "passphrase".toCharArray();
+    private static final List<TestParameters> TESTS = new ArrayList<>(3);
+    private static final List<Exception> EXCEPTIONS = new ArrayList<>(1);
+    private static final String CLIENT_PUBLIC_KEY
+        = "-----BEGIN CERTIFICATE-----\n"
+        + "MIICtTCCAh4CCQDkYJ46DMcGRjANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n"
+        + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n"
+        + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n"
+        + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n"
+        + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n"
+        + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n"
+        + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n"
+        + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IENsaWVudCAoMTAyNCBiaXQg\n"
+        + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAm5rwjmhO7Nwd5GWs+KvQ\n"
+        + "UnDiqpRDvRriOUFdF0rCI2Op24C+iwUMDGxPsgP7VkUpOdJhw3c72aP0CAWcZ5dN\n"
+        + "UCW7WVDAxnogCahLCir1jjoGdEjiNGOy0L9sypsM9UvBzJN8uvXsxsTZX4Z88cKU\n"
+        + "G7RUvN8LQ88zDljk5zr3c2MCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA7LUDrzHln\n"
+        + "EXuGmwZeeroACB6DVtkClMskF/Pj5GnTxoeNN9DggycX/eOeIDKRloHuMpBeZPJH\n"
+        + "NUwFu4LB6HBDeldQD9iRp8zD/fPakOdN+1Gk5hciIZZJ5hQmeCl7Va2Gr64vUqZG\n"
+        + "MkVU755t+7ByLgzWuhPhhsX9QCuPR5FjvQ==\n"
+        + "-----END CERTIFICATE-----";
+
+    private static final String CLIENT_PRIVATE_KEY
+        = "-----BEGIN PRIVATE KEY-----\n"
+        + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJua8I5oTuzcHeRl\n"
+        + "rPir0FJw4qqUQ70a4jlBXRdKwiNjqduAvosFDAxsT7ID+1ZFKTnSYcN3O9mj9AgF\n"
+        + "nGeXTVAlu1lQwMZ6IAmoSwoq9Y46BnRI4jRjstC/bMqbDPVLwcyTfLr17MbE2V+G\n"
+        + "fPHClBu0VLzfC0PPMw5Y5Oc693NjAgMBAAECgYA5w73zj8Nk6J3sMNaShe3S/PcY\n"
+        + "TewLopRCnwI46FbDnnbq9pNFtnzvi7HWKuY983THc1M5peTA+b1Y0QRr7F4Vg4x9\n"
+        + "9UM0B/tZcIIcJJ3LS+9fXKCbYLQWq5F05JqeZu+i+QLmJFO5+2p7laeQ4oQfW7QE\n"
+        + "YR4u2mSaLe0SsqHvOQJBAMhgcye9C6pJO0eo2/VtRxAXI7zxNAIjHwKo1cva7bhu\n"
+        + "GdrMaEAJBAsMJ1GEk7/WDI+3KEbTjQdfIJuAvOR4FXUCQQDGzNn/tl2k93v/ugyM\n"
+        + "/tBhCKDipYDIbyJMoG2AOtOGmCsiGo5L7idO4OAcm/QiHBQMXjFIVgTUcH8MhGj4\n"
+        + "blJ3AkA5fUqsxRV6tuYWKkFpif/QgwMS65VDY7Y6+hvVECwSNSyf1PO4I54QWV1S\n"
+        + "ixok+RHDjgY1Q+77hXSCiQ4o8rcdAkBHvjfR+5sx5IpgUGElJPRIgFenU3j1XH3x\n"
+        + "T1gVFaWuhg3S4eiGaGzRH4BhcrqY8K8fg4Kfi0N08yA2gTZsqUujAkEAjuNPTuKx\n"
+        + "ti0LXI09kbGUqOpRMm1zW5TD6LFeEaUN6oxrSZI2YUvu7VyotAqsxX5O0u0f3VQw\n"
+        + "ySF0Q1oZ6qu7cg==\n"
+        + "-----END PRIVATE KEY-----";
+    private static final String SERVER_PUBLIC_KEY
+        = "-----BEGIN CERTIFICATE-----\n"
+        + "MIICtTCCAh4CCQDkYJ46DMcGRTANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n"
+        + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n"
+        + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n"
+        + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n"
+        + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n"
+        + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n"
+        + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n"
+        + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IFNlcnZlciAoMTAyNCBiaXQg\n"
+        + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArsHHeZ1O67yuxQKDSAOC\n"
+        + "Xm271ViwBrXkxe5cvhG8MCCem6Z3XeZ/m6c2ucRwLaQxnmG1m0G6/OYaUXTivjcG\n"
+        + "/K4bc1I+yjghAWQNLBtsOiP9w0LKibg3TSDehpeuuz/lmB5A4HMqQr8KkY4K7peD\n"
+        + "1QkJ2Dn3zhbwQ/0d8f5CCbkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBOd8XojEnu\n"
+        + "eTUHBwqfmnvRQvbICFDNbbL4KuX/JNPSy1WMGAEbNCTLZ+5yP69js8aUYqAk5vVf\n"
+        + "dWRLU3MDiEzW7zxE1ubuKWjVuyGbG8Me0G01Hw+evBcZqB64Fz3OFISVfQh7MqE/\n"
+        + "O0AeakRMH350FRLNl4o6KBSXmF/AADfqQQ==\n"
+        + "-----END CERTIFICATE-----";
+
+    private static final String SERVER_PRIVATE_KEY
+        = "-----BEGIN PRIVATE KEY-----\n"
+        + "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK7Bx3mdTuu8rsUC\n"
+        + "g0gDgl5tu9VYsAa15MXuXL4RvDAgnpumd13mf5unNrnEcC2kMZ5htZtBuvzmGlF0\n"
+        + "4r43BvyuG3NSPso4IQFkDSwbbDoj/cNCyom4N00g3oaXrrs/5ZgeQOBzKkK/CpGO\n"
+        + "Cu6Xg9UJCdg5984W8EP9HfH+Qgm5AgMBAAECgYAXUv+3qJo+9mjxHHu/IdDFn6nB\n"
+        + "ONwNmTtWe5DfQWi3l7LznU0zOC9x6+hu9NvwC4kf1XSyqxw04tVCZ/JXZurEmEBz\n"
+        + "YtcQ5idRQDkKYXEDOeVUfvtHO6xilzrhPKxxd0GG/sei2pozikkqnYF3OcP0qL+a\n"
+        + "3nWixZQBRoF2nIRLcQJBAN97TJBr0XTRmE7OCKLUy1+ws7vZB9uQ2efHMsgwOpsY\n"
+        + "3cEW5qd95hrxLU72sBeu9loHQgBrT2Q3OAxnsPXmgO0CQQDIL3u9kS/O3Ukx+n1H\n"
+        + "JdPFQCRxrDm/vtJpQEmq+mLqxxnxCFRIYQ2ieAPokBxWeMDtdWJGD3VxhahjPfZm\n"
+        + "5K59AkEAuDVl0tVMfUIWjT5/F9jXGjUIsZofQ/iN5OLpFOHMLPO+Nd6umPjJpwON\n"
+        + "GT11wM/S+DprSPUrJ6vsYy1FTCuHsQJBAMXtnO07xgdE6AAQaRmVnyMiXmY+IQMj\n"
+        + "CyuhsrToyDDWFyIoWB0QSMjg3QxuoHYnAqpGK5qV4ksSGgG13BCz/okCQQCRHTgn\n"
+        + "DuFG2f7GYLFjI4NaTEzHGp+J9LiNYY1kYYLonpwAC3Z5hzJVanYT3/g23AUZ/fdF\n"
+        + "v5PDIViuPo5ZB1eD\n"
+        + "-----END PRIVATE KEY-----";
+
+    private static final String CA_PUBLIC_KEY
+        = "-----BEGIN CERTIFICATE-----\n"
+        + "MIIDCDCCAnGgAwIBAgIJAIYlGfwNBY6NMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD\n"
+        + "VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAd\n"
+        + "BgNVBAoMFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNy\n"
+        + "b3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQDDBZUZXN0IENBICgxMDI0IGJp\n"
+        + "dCBSU0EpMB4XDTA5MDQyNzA0MDQwOFoXDTEzMDYwNTA0MDQwOFowgZwxCzAJBgNV\n"
+        + "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEfMB0G\n"
+        + "A1UECgwWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEmMCQGA1UECwwdU3VuIE1pY3Jv\n"
+        + "c3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAMMFlRlc3QgQ0EgKDEwMjQgYml0\n"
+        + "IFJTQSkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOK4DJxxb0XX6MJ1CVjp\n"
+        + "9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+gdcOA\n"
+        + "GRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4z1q8\n"
+        + "LYbxyMVD1XNNNymvPM44OjsBAgMBAAGjUDBOMB0GA1UdDgQWBBT27BLUflmfdtbi\n"
+        + "WTgjwWnoxop2MTAfBgNVHSMEGDAWgBT27BLUflmfdtbiWTgjwWnoxop2MTAMBgNV\n"
+        + "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEQELNzhZpjnSgigd+QJ6I/3CPDo\n"
+        + "SDkMLdP1BHlT/DkMIZvABm+M09ePNlWiLYCNCsL9nWmX0gw0rFDKsTklZyKTUzaM\n"
+        + "oy/AZCrAaoIc6SO5m1xE1RMyVxd/Y/kg6cbfWxxCJFlMeU5rsSdC97HTE/lDyuoh\n"
+        + "BmlOBB7SdR+1ScjA\n"
+        + "-----END CERTIFICATE-----";
+
+    private static final String CA_PRIVATE_KEY
+        = "-----BEGIN PRIVATE KEY-----\n"
+        + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOK4DJxxb0XX6MJ1\n"
+        + "CVjp9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+g\n"
+        + "dcOAGRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4\n"
+        + "z1q8LYbxyMVD1XNNNymvPM44OjsBAgMBAAECgYEApmMOlk3FrQtsvjGof4GLp3Xa\n"
+        + "tmvs54FzxKhagj0C4UHelNyYpAJ9MLjNiGQ7I31yTeaNrUCAi0XSfsKTSrwbLSnJ\n"
+        + "qsUPKMBrnzcWrOyui2+cupHZXaTlNeYB97teLJYpa6Ql9CZLoTHoim1+//s7diBh\n"
+        + "03Vls+M6Poi5PMvv59UCQQD+k/BiokmbBgWHfBY5cZSlx3Z4VTwSHJmHDTO3Tjso\n"
+        + "EVErXUSVvqD/KHX6eM4VPM8lySV5djWV8lDsESCWMtiLAkEA4/xFNsiOLMQpxW/O\n"
+        + "bt2tukxJkAxldD4lPoFZR+zbXtMtt8OjERtX2wD+nj6h7jfIeSyVuBEcBN8Uj8xe\n"
+        + "kgfgIwJAPbKG4LCqHAsCjgpRrIxNVTwZByLJEy6hOqzFathn19cSj+rjs1Lm28/n\n"
+        + "f9OFRnpdTbAJB/3REM0QNZYVCrG57wJBAN0KuTytZJNouaswhPCew5Kt5mDgc/kp\n"
+        + "S8j3dk2zCto8W8Ygy1iJrzuqEjPxO+UQdrFtlde51vWuKGxnVIW3VwsCQEldqk7r\n"
+        + "8y7PgquPP+k3L0OXno5wGBrPcW1+U0mhIZGnwSzE4SPX2ddqUSEUA/Av4RjAckL/\n"
+        + "fpqmCkpTanyYW9U=\n"
+        + "-----END PRIVATE KEY-----";
+
+    private final SSLSocketFactory factory;
+    private final X509ExtendedKeyManager clientKeyManager;
+    private final X509ExtendedKeyManager serverKeyManager;
+    private final X509TrustManager clientTrustManager;
+    private final X509TrustManager serverTrustManager;
+
+    static abstract class Server implements Runnable {
+
+        final CipherTestUtils cipherTest;
+
+        Server(CipherTestUtils cipherTest) throws Exception {
+            this.cipherTest = cipherTest;
+        }
+
+        @Override
+        public abstract void run();
+
+        void handleRequest(InputStream in, OutputStream out)
+                throws IOException {
+            boolean newline = false;
+            StringBuilder sb = new StringBuilder();
+            while (true) {
+                int ch = in.read();
+                if (ch < 0) {
+                    throw new EOFException();
+                }
+                sb.append((char) ch);
+                if (ch == '\r') {
+                    // empty
+                } else if (ch == '\n') {
+                    if (newline) {
+                        // 2nd newline in a row, end of request
+                        break;
+                    }
+                    newline = true;
+                } else {
+                    newline = false;
+                }
+            }
+            String request = sb.toString();
+            if (request.startsWith("GET / HTTP/1.") == false) {
+                throw new IOException("Invalid request: " + request);
+            }
+            out.write("HTTP/1.0 200 OK\r\n\r\n".getBytes());
+            out.write("Tested Scenario: ".getBytes());
+            TestParameters tp = (TestParameters) CipherTestUtils.TESTS.get(0);
+            out.write(tp.toString().getBytes());
+            out.write(" Test PASSED.".getBytes());
+        }
+    }
+
+    public static class TestParameters {
+
+        String cipherSuite;
+        String protocol;
+        String clientAuth;
+
+        TestParameters(String cipherSuite, String protocol,
+                String clientAuth) {
+            this.cipherSuite = cipherSuite;
+            this.protocol = protocol;
+            this.clientAuth = clientAuth;
+        }
+
+        boolean isEnabled() {
+            return true;
+        }
+
+        @Override
+        public String toString() {
+            String s = cipherSuite + " in " + protocol + " mode";
+            if (clientAuth != null) {
+                s += " with " + clientAuth + " client authentication";
+            }
+            return s;
+        }
+    }
+
+    private static volatile CipherTestUtils instnace = null;
+
+    public static CipherTestUtils getInstance() throws IOException,
+            FileNotFoundException, KeyStoreException,
+            NoSuchAlgorithmException, CertificateException,
+            UnrecoverableKeyException, InvalidKeySpecException {
+        if (instnace == null) {
+            synchronized (CipherTestUtils.class) {
+                if (instnace == null) {
+                    instnace = new CipherTestUtils();
+                }
+            }
+        }
+        return instnace;
+    }
+
+    public static void setTestedArguments(String testedProtocol,
+            String testedCipherSuite) {
+
+        TestParameters testedParams;
+
+        String cipherSuite = testedCipherSuite.trim();
+        if (cipherSuite.startsWith("SSL_")) {
+            testedParams =
+                new TestParameters(cipherSuite, testedProtocol, null);
+            TESTS.add(testedParams);
+
+        } else {
+            System.out.println("Your input Cipher suites is not correct, "
+                    + "please try another one .");
+        }
+    }
+
+    public X509ExtendedKeyManager getClientKeyManager() {
+        return clientKeyManager;
+    }
+
+    public X509TrustManager getClientTrustManager() {
+        return clientTrustManager;
+    }
+
+    public X509ExtendedKeyManager getServerKeyManager() {
+        return serverKeyManager;
+    }
+
+    public X509TrustManager getServerTrustManager() {
+        return serverTrustManager;
+    }
+
+    public static void addFailure(Exception e) {
+        EXCEPTIONS.add(e);
+    }
+
+    private CipherTestUtils()
+            throws IOException, FileNotFoundException, KeyStoreException,
+            NoSuchAlgorithmException, CertificateException,
+            UnrecoverableKeyException, InvalidKeySpecException {
+        factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        KeyStore serverKeyStore = createServerKeyStore(SERVER_PUBLIC_KEY,
+                SERVER_PRIVATE_KEY);
+        KeyStore serverTrustStore = createServerKeyStore(CA_PUBLIC_KEY,
+                CA_PRIVATE_KEY);
+
+        if (serverKeyStore != null) {
+            KeyManagerFactory keyFactory1
+                    = KeyManagerFactory.getInstance(
+                            KeyManagerFactory.getDefaultAlgorithm());
+            keyFactory1.init(serverKeyStore, PASSWORD);
+            serverKeyManager = (X509ExtendedKeyManager) keyFactory1.
+                    getKeyManagers()[0];
+        } else {
+            serverKeyManager = null;
+        }
+        serverTrustManager = serverTrustStore != null
+                ? new AlwaysTrustManager(serverTrustStore) : null;
+
+        KeyStore clientKeyStore, clientTrustStore;
+        clientTrustStore = serverTrustStore;
+        clientKeyStore =
+                createServerKeyStore(CLIENT_PUBLIC_KEY,CLIENT_PRIVATE_KEY);
+        if (clientKeyStore != null) {
+            KeyManagerFactory keyFactory
+                    = KeyManagerFactory.getInstance(
+                            KeyManagerFactory.getDefaultAlgorithm());
+            keyFactory.init(clientKeyStore, PASSWORD);
+            clientKeyManager = (X509ExtendedKeyManager) keyFactory.
+                    getKeyManagers()[0];
+        } else {
+            clientKeyManager = null;
+        }
+        clientTrustManager = (clientTrustStore != null)
+                ? new AlwaysTrustManager(clientTrustStore) : null;
+    }
+
+    void checkResult(String exception) throws Exception {
+        if (EXCEPTIONS.size() >= 1) {
+            Exception actualException = EXCEPTIONS.get(0);
+            if (exception == null) {
+                throw new RuntimeException("FAILED: got unexpected exception: "
+                        + actualException);
+            }
+            if (!exception.equals(actualException.getClass().getName())) {
+                throw new RuntimeException("FAILED: got unexpected exception: "
+                        + actualException);
+            }
+
+            System.out.println("PASSED: got expected exception: "
+                    + actualException);
+        } else {
+            if (exception != null) {
+                throw new RuntimeException("FAILED: " + exception
+                        + " was expected");
+            }
+            System.out.println("PASSED");
+        }
+    }
+
+    SSLSocketFactory getFactory() {
+        return factory;
+    }
+
+    static abstract class Client implements Runnable {
+
+        final CipherTestUtils cipherTest;
+        TestParameters testedParams;
+
+        Client(CipherTestUtils cipherTest) throws Exception {
+            this.cipherTest = cipherTest;
+        }
+
+        Client(CipherTestUtils cipherTest,
+                String testedCipherSuite) throws Exception {
+            this.cipherTest = cipherTest;
+        }
+
+        @Override
+        public final void run() {
+
+            TESTS.stream().map((params) -> {
+                if (!params.isEnabled()) {
+                    System.out.println("Skipping disabled test " + params);
+                }
+                return params;
+            }).forEach((params) -> {
+                try {
+                    runTest(params);
+                    System.out.println("Passed " + params);
+                } catch (Exception e) {
+                    CipherTestUtils.addFailure(e);
+                    System.out.println("** Failed " + params
+                            + "**, got exception:");
+                    e.printStackTrace(System.err);
+                }
+            });
+        }
+
+        abstract void runTest(TestParameters params) throws Exception;
+
+        void sendRequest(InputStream in, OutputStream out) throws IOException {
+            out.write("GET / HTTP/1.0\r\n\r\n".getBytes());
+            out.flush();
+            StringBuilder sb = new StringBuilder();
+            while (true) {
+                int ch = in.read();
+                if (ch < 0) {
+                    break;
+                }
+                sb.append((char) ch);
+            }
+            String response = sb.toString();
+            if (response.startsWith("HTTP/1.0 200 ") == false) {
+                throw new IOException("Invalid response: " + response);
+            } else {
+                System.out.println();
+                System.out.println("--- Response --- ");
+                System.out.println(response);
+                System.out.println("---------------- ");
+            }
+        }
+    }
+
+    public static void printStringArray(String[] stringArray) {
+        System.out.print(stringArray.length + " : ");
+        for (String stringArray1 : stringArray) {
+            System.out.print(stringArray1);
+            System.out.print(",");
+        }
+        System.out.println();
+    }
+
+    public static void printInfo(SSLServerSocket socket) {
+        System.out.println();
+        System.out.println("--- SSL ServerSocket Info ---");
+        System.out.print("SupportedProtocols    : ");
+        printStringArray(socket.getSupportedProtocols());
+        System.out.print("SupportedCipherSuites : ");
+        printStringArray(socket.getSupportedCipherSuites());
+        System.out.print("EnabledProtocols      : ");
+        printStringArray(socket.getEnabledProtocols());
+        System.out.print("EnabledCipherSuites   : ");
+        String[] supportedCipherSuites = socket.getEnabledCipherSuites();
+        Arrays.sort(supportedCipherSuites);
+        printStringArray(supportedCipherSuites);
+        System.out.println("NeedClientAuth        : "
+                + socket.getNeedClientAuth());
+        System.out.println("WantClientAuth        : "
+                + socket.getWantClientAuth());
+        System.out.println("-----------------------");
+    }
+
+    public static void printInfo(SSLSocket socket) {
+        System.out.println();
+        System.out.println("--- SSL Socket Info ---");
+        System.out.print(" SupportedProtocols    : ");
+        printStringArray(socket.getSupportedProtocols());
+        System.out.println(" EnabledProtocols      : "
+                + socket.getEnabledProtocols()[0]);
+        System.out.print(" SupportedCipherSuites : ");
+        String[] supportedCipherSuites = socket.getEnabledCipherSuites();
+        Arrays.sort(supportedCipherSuites);
+        printStringArray(supportedCipherSuites);
+        System.out.println(" EnabledCipherSuites   : "
+                + socket.getEnabledCipherSuites()[0]);
+        System.out.println(" NeedClientAuth        : "
+                + socket.getNeedClientAuth());
+        System.out.println(" WantClientAuth        : "
+                + socket.getWantClientAuth());
+        System.out.println("-----------------------");
+    }
+
+    private static KeyStore createServerKeyStore(String publicKeyStr,
+            String keySpecStr) throws KeyStoreException, IOException,
+            NoSuchAlgorithmException, CertificateException,
+            InvalidKeySpecException {
+
+        KeyStore ks = KeyStore.getInstance("JKS");
+        ks.load(null, null);
+        if (publicKeyStr == null || keySpecStr == null) {
+            throw new IllegalArgumentException("publicKeyStr or "
+                    + "keySpecStr cannot be null");
+        }
+        String strippedPrivateKey = keySpecStr.substring(
+                keySpecStr.indexOf("\n"), keySpecStr.lastIndexOf("\n"));
+
+        // generate the private key.
+        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
+                Base64.getMimeDecoder().decode(strippedPrivateKey));
+        KeyFactory kf = KeyFactory.getInstance("RSA");
+        RSAPrivateKey priKey
+                = (RSAPrivateKey) kf.generatePrivate(priKeySpec);
+
+        // generate certificate chain
+        try (InputStream is =
+                new ByteArrayInputStream(publicKeyStr.getBytes())) {
+            // generate certificate from cert string
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            Certificate keyCert = cf.generateCertificate(is);
+            Certificate[] chain = {keyCert};
+            ks.setKeyEntry("TestEntry", priKey, PASSWORD, chain);
+        }
+
+        return ks;
+    }
+
+    public static void main(PeerFactory peerFactory, String mode,
+            String expectedException)
+            throws Exception {
+        long time = System.currentTimeMillis();
+        setTestedArguments(peerFactory.getTestedProtocol(),
+                peerFactory.getTestedCipher());
+
+        System.out.print(
+                " Initializing test '" + peerFactory.getName() + "'...");
+        secureRandom.nextInt();
+
+        CipherTestUtils cipherTest = CipherTestUtils.getInstance();
+        if (mode.equalsIgnoreCase("Server")) {  // server mode
+            Thread serverThread = new Thread(peerFactory.newServer(cipherTest),
+                    "Server");
+            serverThread.start();
+        } else if (mode.equalsIgnoreCase("Client")) {
+            peerFactory.newClient(cipherTest).run();
+            cipherTest.checkResult(expectedException);
+            JSSEServer.closeServer = true;
+        } else {
+            throw new RuntimeException("unsupported mode");
+        }
+        time = System.currentTimeMillis() - time;
+        System.out.println("Elapsed time " + time);
+
+    }
+
+    public static abstract class PeerFactory {
+
+        abstract String getName();
+
+        abstract String getTestedProtocol();
+
+        abstract String getTestedCipher();
+
+        abstract Client newClient(CipherTestUtils cipherTest) throws Exception;
+
+        abstract Server newServer(CipherTestUtils cipherTest) throws Exception;
+
+        boolean isSupported(String cipherSuite) {
+            return true;
+        }
+    }
+}
+
+class AlwaysTrustManager implements X509TrustManager {
+
+    X509TrustManager trustManager;
+
+    public AlwaysTrustManager(KeyStore keyStore)
+            throws NoSuchAlgorithmException, KeyStoreException {
+
+        TrustManagerFactory tmf
+                = TrustManagerFactory.getInstance(TrustManagerFactory.
+                        getDefaultAlgorithm());
+        tmf.init(keyStore);
+
+        TrustManager tms[] = tmf.getTrustManagers();
+        for (TrustManager tm : tms) {
+            trustManager = (X509TrustManager) tm;
+            return;
+        }
+
+    }
+
+    @Override
+    public void checkClientTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        try {
+            trustManager.checkClientTrusted(chain, authType);
+        } catch (CertificateException excep) {
+            System.out.println("ERROR in client trust manager");
+        }
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] chain, String authType)
+            throws CertificateException {
+        try {
+            trustManager.checkServerTrusted(chain, authType);
+        } catch (CertificateException excep) {
+            System.out.println("ERROR in server Trust manger");
+        }
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return trustManager.getAcceptedIssuers();
+    }
+}
+
+class MyX509KeyManager extends X509ExtendedKeyManager {
+
+    private final X509ExtendedKeyManager keyManager;
+    private String authType;
+
+    MyX509KeyManager(X509ExtendedKeyManager keyManager) {
+        this.keyManager = keyManager;
+    }
+
+    void setAuthType(String authType) {
+        this.authType = "ECDSA".equals(authType) ? "EC" : authType;
+    }
+
+    @Override
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        if (authType == null) {
+            return null;
+        }
+        return keyManager.getClientAliases(authType, issuers);
+    }
+
+    @Override
+    public String chooseClientAlias(String[] keyType, Principal[] issuers,
+            Socket socket) {
+        if (authType == null) {
+            return null;
+        }
+        return keyManager.chooseClientAlias(new String[]{authType},
+                issuers, socket);
+    }
+
+    @Override
+    public String chooseEngineClientAlias(String[] keyType,
+            Principal[] issuers, SSLEngine engine) {
+        if (authType == null) {
+            return null;
+        }
+        return keyManager.chooseEngineClientAlias(new String[]{authType},
+                issuers, engine);
+    }
+
+    @Override
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        throw new UnsupportedOperationException("Servers not supported");
+    }
+
+    @Override
+    public String chooseServerAlias(String keyType, Principal[] issuers,
+            Socket socket) {
+        throw new UnsupportedOperationException("Servers not supported");
+    }
+
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers,
+            SSLEngine engine) {
+        throw new UnsupportedOperationException("Servers not supported");
+    }
+
+    @Override
+    public X509Certificate[] getCertificateChain(String alias) {
+        return keyManager.getCertificateChain(alias);
+    }
+
+    @Override
+    public PrivateKey getPrivateKey(String alias) {
+        return keyManager.getPrivateKey(alias);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/JSSEClient.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 only, as published by
+ * the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more
+ * details (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version 2
+ * along with this work; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or
+ * visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.cert.Certificate;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+class JSSEClient extends CipherTestUtils.Client {
+
+    private static final String DEFAULT = "DEFAULT";
+    private static final String TLS = "TLS";
+
+    private final SSLContext sslContext;
+    private final MyX509KeyManager keyManager;
+    private final int serverPort;
+    private final String serverHost;
+    private final String testedProtocol;
+
+    JSSEClient(CipherTestUtils cipherTest, String serverHost, int serverPort,
+            String testedProtocols, String testedCipherSuite) throws Exception {
+        super(cipherTest, testedCipherSuite);
+        this.serverHost = serverHost;
+        this.serverPort = serverPort;
+        this.testedProtocol = testedProtocols;
+        this.keyManager =
+                new MyX509KeyManager(cipherTest.getClientKeyManager());
+        sslContext = SSLContext.getInstance(TLS);
+    }
+
+    @Override
+    void runTest(CipherTestUtils.TestParameters params) throws Exception {
+        SSLSocket socket = null;
+        try {
+            System.out.println("Connecting to server...");
+            keyManager.setAuthType(params.clientAuth);
+            sslContext.init(new KeyManager[]{keyManager},
+                    new TrustManager[]{cipherTest.getClientTrustManager()},
+                    CipherTestUtils.secureRandom);
+            SSLSocketFactory factory = (SSLSocketFactory) sslContext.
+                    getSocketFactory();
+            socket = (SSLSocket) factory.createSocket(serverHost,
+                    serverPort);
+            socket.setSoTimeout(CipherTestUtils.TIMEOUT);
+            socket.setEnabledCipherSuites(params.cipherSuite.split(","));
+            if (params.protocol != null && !params.protocol.trim().equals("")
+                    && !params.protocol.trim().equals(DEFAULT)) {
+                socket.setEnabledProtocols(params.protocol.split(","));
+            }
+            CipherTestUtils.printInfo(socket);
+            InputStream in = socket.getInputStream();
+            OutputStream out = socket.getOutputStream();
+            sendRequest(in, out);
+            SSLSession session = socket.getSession();
+            session.invalidate();
+            String cipherSuite = session.getCipherSuite();
+            if (params.cipherSuite.equals(cipherSuite) == false) {
+                throw new RuntimeException("Negotiated ciphersuite mismatch: "
+                        + cipherSuite + " != " + params.cipherSuite);
+            }
+            String protocol = session.getProtocol();
+            if (!DEFAULT.equals(params.protocol)
+                    && !params.protocol.contains(protocol)) {
+                throw new RuntimeException("Negotiated protocol mismatch: "
+                        + protocol + " != " + params.protocol);
+            }
+            if (!cipherSuite.contains("DH_anon")) {
+                session.getPeerCertificates();
+            }
+            Certificate[] certificates = session.getLocalCertificates();
+            if (params.clientAuth == null) {
+                if (certificates != null) {
+                    throw new RuntimeException("Local certificates "
+                            + "should be null");
+                }
+            } else {
+                if ((certificates == null) || (certificates.length == 0)) {
+                    throw new RuntimeException("Certificates missing");
+                }
+                String keyAlg = certificates[0].getPublicKey().getAlgorithm();
+                if ("EC".equals(keyAlg)) {
+                    keyAlg = "ECDSA";
+                }
+                if (params.clientAuth == null ? keyAlg != null
+                        : !params.clientAuth.equals(keyAlg)) {
+                    throw new RuntimeException("Certificate type mismatch: "
+                            + keyAlg + " != " + params.clientAuth);
+                }
+            }
+        } finally {
+            if (socket != null) {
+                socket.close();
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/JSSEServer.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 only, as published by
+ * the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more
+ * details (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version 2
+ * along with this work; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or
+ * visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+
+public class JSSEServer extends CipherTestUtils.Server {
+
+    private final SSLServerSocket serverSocket;
+    private final int serverPort;
+    static volatile boolean closeServer = false;
+
+    JSSEServer(CipherTestUtils cipherTest, int serverPort,
+            String protocol, String cipherSuite) throws Exception {
+        super(cipherTest);
+        this.serverPort = serverPort;
+        SSLContext serverContext = SSLContext.getInstance("TLS");
+        serverContext.init(new KeyManager[]{cipherTest.getServerKeyManager()},
+                new TrustManager[]{cipherTest.getServerTrustManager()},
+                CipherTestUtils.secureRandom);
+        SSLServerSocketFactory factory =
+                (SSLServerSocketFactory)serverContext.getServerSocketFactory();
+        serverSocket =
+                (SSLServerSocket) factory.createServerSocket(serverPort);
+        serverSocket.setEnabledProtocols(protocol.split(","));
+        serverSocket.setEnabledCipherSuites(cipherSuite.split(","));
+
+        CipherTestUtils.printInfo(serverSocket);
+    }
+
+    @Override
+    public void run() {
+        System.out.println("JSSE Server listening on port " + serverPort);
+        while (!closeServer) {
+            try (final SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                socket.setSoTimeout(CipherTestUtils.TIMEOUT);
+
+                try (InputStream in = socket.getInputStream();
+                        OutputStream out = socket.getOutputStream()) {
+                    handleRequest(in, out);
+                    out.flush();
+                } catch (IOException e) {
+                    CipherTestUtils.addFailure(e);
+                    System.out.println("Got IOException:");
+                    e.printStackTrace(System.err);
+                }
+            } catch (Exception e) {
+                CipherTestUtils.addFailure(e);
+                System.out.println("Exception:");
+                e.printStackTrace(System.err);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/TLS/TestJSSE.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2010, 2014, 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 static java.lang.System.out;
+import java.security.Provider;
+import java.security.Security;
+
+/**
+ * @test
+ * @bug 8049429
+ * @library ../../../../lib/testlibrary/
+ * @build jdk.testlibrary.Utils
+ * @compile CipherTestUtils.java JSSEClient.java JSSEServer.java
+ * @summary Test that all cipher suites work in all versions and all client
+ * authentication types. The way this is setup the server is stateless and
+ * all checking is done on the client side.
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3
+ *        -DCLIENT_PROTOCOL=SSLv3
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1
+ *        -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1.1
+ *        -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1.2
+ *        -DCLIENT_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1
+ *        -DCLIENT_PROTOCOL=TLSv1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1
+ *        -DCLIENT_PROTOCOL=TLSv1.1 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3
+ *        -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ *        TestJSSE javax.net.ssl.SSLHandshakeException
+ * @run main/othervm -DSERVER_PROTOCOL=TLSv1
+ *        -DCLIENT_PROTOCOL=TLSv1.1,TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ *        TestJSSE javax.net.ssl.SSLHandshakeException
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCLIENT_PROTOCOL=TLSv1.2 -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1
+ *        -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCLIENT_PROTOCOL=DEFAULT -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1,TLSv1.1,TLSv1.2
+ *        -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5 TestJSSE
+ * @run main/othervm -DSERVER_PROTOCOL=SSLv2Hello,SSLv3,TLSv1
+ *        -DCLIENT_PROTOCOL=DEFAULT -Djdk.tls.client.protocols=TLSv1.2
+ *        -DCIPHER=SSL_RSA_WITH_RC4_128_MD5
+ *        TestJSSE javax.net.ssl.SSLHandshakeException
+ *
+ */
+
+public class TestJSSE {
+
+    private static final String LOCAL_IP = "127.0.0.1";
+
+    public static void main(String... args) throws Exception {
+        String serverProtocol = System.getProperty("SERVER_PROTOCOL");
+        String clientProtocol = System.getProperty("CLIENT_PROTOCOL");
+        int port = jdk.testlibrary.Utils.getFreePort();
+        String cipher = System.getProperty("CIPHER");
+        if (serverProtocol == null
+                || clientProtocol == null
+                || cipher == null) {
+            throw new IllegalArgumentException("SERVER_PROTOCOL "
+                    + "or CLIENT_PROTOCOL or CIPHER is missing");
+        }
+        out.println("ServerProtocol =" + serverProtocol);
+        out.println("ClientProtocol =" + clientProtocol);
+        out.println("Cipher         =" + cipher);
+        server(serverProtocol, cipher, port, args);
+        client(port, clientProtocol, cipher, args);
+
+    }
+
+    public static void client(int testPort,
+            String testProtocols, String testCipher,
+            String... exception) throws Exception {
+        String expectedException = exception.length >= 1
+                ? exception[0] : null;
+        out.println("=========================================");
+        out.println(" Testing - https://" + LOCAL_IP + ":" + testPort);
+        out.println(" Testing - Protocol : " + testProtocols);
+        out.println(" Testing - Cipher : " + testCipher);
+        Provider p = new sun.security.ec.SunEC();
+        Security.insertProviderAt(p, 1);
+        try {
+            CipherTestUtils.main(new JSSEFactory(LOCAL_IP,
+                    testPort, testProtocols,
+                    testCipher, "client JSSE"),
+                    "client", expectedException);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void server(String testProtocol, String testCipher,
+            int testPort,
+            String... exception) throws Exception {
+        String expectedException = exception.length >= 1
+                ? exception[0] : null;
+        out.println(" This is Server");
+        out.println(" Testing Protocol: " + testProtocol);
+        out.println(" Testing Cipher: " + testCipher);
+        out.println(" Testing Port: " + testPort);
+        Provider p = new sun.security.ec.SunEC();
+        Security.insertProviderAt(p, 1);
+        try {
+            CipherTestUtils.main(new JSSEFactory(null, testPort,
+                    testProtocol, testCipher, "Server JSSE"),
+                    "Server", expectedException);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static class JSSEFactory extends CipherTestUtils.PeerFactory {
+
+        final String testedCipherSuite, testedProtocol, testHost;
+        final int testPort;
+        final String name;
+
+        JSSEFactory(String testHost, int testPort, String testedProtocol,
+                String testedCipherSuite, String name) {
+            this.testedCipherSuite = testedCipherSuite;
+            this.testedProtocol = testedProtocol;
+            this.testHost = testHost;
+            this.testPort = testPort;
+            this.name = name;
+        }
+
+        @Override
+        String getName() {
+            return name;
+        }
+
+        @Override
+        String getTestedCipher() {
+            return testedCipherSuite;
+        }
+
+        @Override
+        String getTestedProtocol() {
+            return testedProtocol;
+        }
+
+        @Override
+        CipherTestUtils.Client newClient(CipherTestUtils cipherTest)
+                throws Exception {
+            return new JSSEClient(cipherTest, testHost, testPort,
+                    testedProtocol, testedCipherSuite);
+        }
+
+        @Override
+        CipherTestUtils.Server newServer(CipherTestUtils cipherTest)
+                throws Exception {
+            return new JSSEServer(cipherTest, testPort,
+                    testedProtocol, testedCipherSuite);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/test/rowset/spi/SyncFactoryPermissionsTests.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.rowset.spi;
+
+import java.security.AccessControlException;
+import java.security.Policy;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.rowset.spi.SyncFactory;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import util.BaseTest;
+import util.TestPolicy;
+
+public class SyncFactoryPermissionsTests extends BaseTest {
+
+    Context ctx;
+    private static Policy policy;
+    private static SecurityManager sm;
+
+    /*
+     * Install a SeeurityManager along with a base Policy to allow testNG to run
+     */
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        setPolicy(new TestPolicy());
+        System.setSecurityManager(new SecurityManager());
+    }
+
+    /*
+     * Install the original Policy and SecurityManager
+     */
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+        System.setSecurityManager(sm);
+        setPolicy(policy);
+    }
+
+    /*
+     * Initialize a Context to be used in our tests.
+     * Save off the original Policy and SecurityManager
+     */
+    public SyncFactoryPermissionsTests() {
+        policy = Policy.getPolicy();
+        sm = System.getSecurityManager();
+
+        try {
+            ctx = new InitialContext();
+        } catch (NamingException ex) {
+            Logger.getLogger(SyncFactoryPermissionsTests.class.getName()).
+                    log(Level.SEVERE, null, ex);
+        }
+    }
+
+    /*
+     * Validate that AccessControlException is thrown if
+     * SQLPermission("setSyncFactory") has not been granted
+     */
+    @Test(expectedExceptions = AccessControlException.class)
+    public void test() throws Exception {
+        setPolicy(new TestPolicy());
+        SyncFactory.setJNDIContext(ctx);
+    }
+
+    /*
+     * Validate that setJNDIContext succeeds if SQLPermission("setSyncFactory")
+     * has been granted
+     */
+    @Test
+    public void test1() throws Exception {
+        Policy.setPolicy(new TestPolicy("setSyncFactory"));
+        SyncFactory.setJNDIContext(ctx);
+    }
+
+    /*
+     * Validate that setJNDIContext succeeds if AllPermissions has been granted
+     */
+    @Test
+    public void test2() throws Exception {
+        setPolicy(new TestPolicy("all"));
+        SyncFactory.setJNDIContext(ctx);
+    }
+}
--- a/jdk/test/javax/sql/testng/util/BaseTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/javax/sql/testng/util/BaseTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -27,6 +27,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.security.Policy;
 import java.sql.SQLException;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
@@ -88,4 +89,11 @@
         }
         return o1;
     }
+
+    /*
+     * Utility Method used to set the current Policy
+     */
+    protected static void setPolicy(Policy p) {
+        Policy.setPolicy(p);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sql/testng/util/TestPolicy.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.io.FilePermission;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+import java.sql.SQLPermission;
+import java.util.Enumeration;
+import java.util.PropertyPermission;
+import java.util.StringJoiner;
+
+/*
+ * Simple Policy class that supports the required Permissions to validate the
+ * JDBC concrete classes
+ */
+public class TestPolicy extends Policy {
+
+    final PermissionCollection permissions = new Permissions();
+
+    /**
+     * Constructor which sets the minimum permissions allowing testNG to work
+     * with a SecurityManager
+     */
+    public TestPolicy() {
+        setMinimalPermissions();
+    }
+
+    /*
+     * Constructor which determines which permissions are defined for this
+     * Policy used by the JDBC tests Possible values are: all (ALLPermissions),
+     * setLog (SQLPemission("setLog"), deregisterDriver
+     * (SQLPermission("deregisterDriver") (SQLPermission("deregisterDriver"),
+     * and setSyncFactory(SQLPermission(setSyncFactory),
+     *
+     * @param policy Permissions to set
+     */
+    public TestPolicy(String policy) {
+
+        switch (policy) {
+            case "all":
+                permissions.add(new AllPermission());
+                break;
+            case "setLog":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("setLog"));
+                break;
+            case "deregisterDriver":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("deregisterDriver"));
+                break;
+            case "setSyncFactory":
+                setMinimalPermissions();
+                permissions.add(new SQLPermission("setSyncFactory"));
+                break;
+            default:
+                setMinimalPermissions();
+        }
+    }
+
+    /*
+     * Defines the minimal permissions required by testNG when running these
+     * tests
+     */
+    private void setMinimalPermissions() {
+        permissions.add(new SecurityPermission("getPolicy"));
+        permissions.add(new SecurityPermission("setPolicy"));
+        permissions.add(new RuntimePermission("getClassLoader"));
+        permissions.add(new RuntimePermission("setSecurityManager"));
+        permissions.add(new RuntimePermission("createSecurityManager"));
+        permissions.add(new PropertyPermission("testng.show.stack.frames",
+                "read"));
+        permissions.add(new PropertyPermission("line.separator", "read"));
+        permissions.add(new PropertyPermission("fileStringBuffer", "read"));
+        permissions.add(new PropertyPermission("dataproviderthreadcount", "read"));
+        permissions.add(new PropertyPermission("java.io.tmpdir", "read"));
+        permissions.add(new FilePermission("<<ALL FILES>>",
+                "read, write, delete"));
+    }
+
+    /*
+     * Overloaded methods from the Policy class
+     */
+    @Override
+    public String toString() {
+        StringJoiner sj = new StringJoiner("\n", "policy: ", "");
+        Enumeration<Permission> perms = permissions.elements();
+        while (perms.hasMoreElements()) {
+            sj.add(perms.nextElement().toString());
+        }
+        return sj.toString();
+
+    }
+
+    @Override
+    public PermissionCollection getPermissions(ProtectionDomain domain) {
+        return permissions;
+    }
+
+    @Override
+    public PermissionCollection getPermissions(CodeSource codesource) {
+        return permissions;
+    }
+
+    @Override
+    public boolean implies(ProtectionDomain domain, Permission perm) {
+        return permissions.implies(perm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/BaseTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.net.URL;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.impl.Constants;
+import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
+import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import com.sun.org.apache.xerces.internal.xs.XSElementDeclaration;
+import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
+import javax.xml.transform.stream.StreamSource;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+public abstract class BaseTest {
+    protected final static String ROOT_TYPE = Constants.XERCES_PROPERTY_PREFIX
+            + Constants.ROOT_TYPE_DEFINITION_PROPERTY;
+
+    protected final static String IGNORE_XSI_TYPE = Constants.XERCES_FEATURE_PREFIX
+            + Constants.IGNORE_XSI_TYPE_FEATURE;
+
+    protected final static String ID_IDREF_CHECKING = Constants.XERCES_FEATURE_PREFIX
+            + Constants.ID_IDREF_CHECKING_FEATURE;
+
+    protected final static String IDC_CHECKING = Constants.XERCES_FEATURE_PREFIX
+            + Constants.IDC_CHECKING_FEATURE;
+
+    protected final static String UNPARSED_ENTITY_CHECKING = Constants.XERCES_FEATURE_PREFIX
+            + Constants.UNPARSED_ENTITY_CHECKING_FEATURE;
+
+    protected final static String USE_GRAMMAR_POOL_ONLY = Constants.XERCES_FEATURE_PREFIX
+            + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
+
+    protected final static String DYNAMIC_VALIDATION = Constants.XERCES_FEATURE_PREFIX
+            + Constants.DYNAMIC_VALIDATION_FEATURE;
+
+    protected final static String DOCUMENT_CLASS_NAME = Constants.XERCES_PROPERTY_PREFIX
+            + Constants.DOCUMENT_CLASS_NAME_PROPERTY;
+
+    protected Schema schema;
+    protected Validator fValidator;
+
+    protected SpecialCaseErrorHandler fErrorHandler;
+
+    DocumentBuilder builder;
+    protected Document fDocument;
+
+    protected ElementPSVI fRootNode;
+
+    protected URL fDocumentURL;
+    protected String documentPath;
+    protected String fDocumentId;
+
+    static String errMessage;
+
+    int passed = 0, failed = 0;
+
+    public static boolean isWindows = false;
+    static {
+        if (System.getProperty("os.name").indexOf("Windows")>-1) {
+            isWindows = true;
+        }
+    };
+    public static final String USER_DIR = System.getProperty("user.dir", ".");
+    public static final String BASE_DIR = System.getProperty("test.src", USER_DIR)
+            .replaceAll("\\" + System.getProperty("file.separator"), "/");
+
+    protected abstract String getSchemaFile();
+
+    protected abstract String getXMLDocument();
+
+    public BaseTest(String name) {
+        fErrorHandler = new SpecialCaseErrorHandler(getRelevantErrorIDs());
+    }
+
+    protected void setUp() throws Exception {
+
+        DocumentBuilderFactory docFactory = DocumentBuilderFactory
+                .newInstance();
+        docFactory.setAttribute(DOCUMENT_CLASS_NAME,
+                "com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl");
+        docFactory.setNamespaceAware(true);
+        builder = docFactory.newDocumentBuilder();
+
+        documentPath = BASE_DIR + "/" + getXMLDocument();
+System.out.println("documentPath:"+documentPath);
+        if (isWindows) {
+            fDocumentId = "file:/" + documentPath;
+        } else {
+            fDocumentId = "file:" + documentPath;
+        }
+        //fDocumentURL = ClassLoader.getSystemResource(documentPath);
+        //fDocumentURL = getClass().getResource(documentPath);
+System.out.println("fDocumentId:"+fDocumentId);
+//System.out.println("fDocumentURL.toExternalForm:"+fDocumentURL.toExternalForm());
+/**
+        if (fDocumentURL == null) {
+            throw new FileNotFoundException("Couldn't find xml file for test: " + documentPath);
+        }
+        fDocument = builder.parse(fDocumentURL.toExternalForm());
+        fRootNode = (ElementPSVI) fDocument.getDocumentElement();
+        */
+        SchemaFactory sf = SchemaFactory
+                .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        sf.setFeature(USE_GRAMMAR_POOL_ONLY, getUseGrammarPoolOnly());
+        String schemaPath = BASE_DIR + "/" + getSchemaFile();
+        /**
+        URL schemaURL = ClassLoader.getSystemResource(schemaPath);
+        if (schemaURL == null) {
+            throw new FileNotFoundException("Couldn't find schema file for test: " + schemaPath);
+        }
+        */
+        schema = sf.newSchema(new StreamSource(new File(schemaPath)));
+    }
+
+    protected void tearDown() throws Exception {
+        fValidator = null;
+        fDocument = null;
+        fRootNode = null;
+        fErrorHandler.reset();
+        System.out.println("\nNumber of tests passed: " + passed);
+        System.out.println("Number of tests failed: " + failed + "\n");
+
+        if (errMessage != null) {
+            throw new RuntimeException(errMessage);
+        }
+    }
+
+    protected void validateDocument() throws Exception {
+        Source source = new DOMSource(fDocument);
+        source.setSystemId(fDocumentId);
+        Result result = new DOMResult(fDocument);
+        fValidator.validate(source, result);
+    }
+
+    protected void validateFragment() throws Exception {
+        Source source = new DOMSource((Node) fRootNode);
+        source.setSystemId(fDocumentId);
+        Result result = new DOMResult((Node) fRootNode);
+        fValidator.validate(source, result);
+    }
+
+    protected void reset() throws Exception {
+        try {
+System.out.println("new File(documentPath)" + new File(documentPath));
+
+        fDocument = builder.parse(new File(documentPath));
+        fRootNode = (ElementPSVI) fDocument.getDocumentElement();
+System.out.println("fDocument" + fDocument);
+System.out.println("fRootNode" + fRootNode);
+        fValidator = schema.newValidator();
+        fErrorHandler.reset();
+        fValidator.setErrorHandler(fErrorHandler);
+        fValidator.setFeature(DYNAMIC_VALIDATION, false);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected PSVIElementNSImpl getChild(int n) {
+        int numFound = 0;
+        Node child = ((Node) fRootNode).getFirstChild();
+        while (child != null) {
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                numFound++;
+                if (numFound == n) {
+                    return (PSVIElementNSImpl) child;
+                }
+            }
+            child = child.getNextSibling();
+        }
+        return null;
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] {};
+    }
+
+    protected boolean getUseGrammarPoolOnly() {
+        return false;
+    }
+
+    // specialized asserts
+
+    protected void assertValidity(short expectedValidity, short actualValidity) {
+        String expectedString = expectedValidity == ItemPSVI.VALIDITY_VALID ? "valid"
+                : (expectedValidity == ItemPSVI.VALIDITY_INVALID ? "invalid"
+                        : "notKnown");
+        String actualString = actualValidity == ItemPSVI.VALIDITY_VALID ? "valid"
+                : (actualValidity == ItemPSVI.VALIDITY_INVALID ? "invalid"
+                        : "notKnown");
+        String message = "{validity} was <" + actualString
+                + "> but it should have been <" + expectedString + ">";
+        assertEquals(message, expectedValidity, actualValidity);
+    }
+
+    protected void assertValidationAttempted(short expectedAttempted,
+            short actualAttempted) {
+        String expectedString = expectedAttempted == ItemPSVI.VALIDATION_FULL ? "full"
+                : (expectedAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial"
+                        : "none");
+        String actualString = actualAttempted == ItemPSVI.VALIDATION_FULL ? "full"
+                : (actualAttempted == ItemPSVI.VALIDATION_PARTIAL ? "partial"
+                        : "none");
+        String message = "{validity} was <" + actualString
+                + "> but it should have been <" + expectedString + ">";
+        assertEquals(message, expectedAttempted, actualAttempted);
+    }
+
+    protected void assertElementName(String expectedName, String actualName) {
+        assertEquals("Local name of element declaration is wrong.",
+                expectedName, actualName);
+    }
+
+    protected void assertElementNull(XSElementDeclaration elem) {
+        assertNull("Element declaration should be null.", elem);
+    }
+
+    protected void assertElementNamespace(String expectedName, String actualName) {
+        assertEquals("Namespace of element declaration is wrong.",
+                expectedName, actualName);
+    }
+
+    protected void assertElementNamespaceNull(String actualName) {
+        assertNull("Local name of element declaration should be null.",
+                actualName);
+    }
+
+    protected void assertTypeName(String expectedName, String actualName) {
+        assertEquals("Local name of type definition is wrong.", expectedName,
+                actualName);
+    }
+
+    protected void assertTypeNull(XSTypeDefinition type) {
+        assertNull("Type definition should be null.", type);
+    }
+
+    protected void assertTypeNamespace(String expectedName, String actualName) {
+        assertEquals("Namespace of type definition is wrong.", expectedName,
+                actualName);
+    }
+
+    protected void assertTypeNamespaceNull(String actualName) {
+        assertNull("Namespace of type definition should be null.", actualName);
+    }
+
+    protected void assertError(String error) {
+        assertTrue("Error <" + error + "> should have occured, but did not.",
+                fErrorHandler.specialCaseFound(error));
+    }
+
+    protected void assertNoError(String error) {
+        assertFalse("Error <" + error
+                + "> should not have occured (but it did)", fErrorHandler
+                .specialCaseFound(error));
+    }
+
+    protected void assertAnyType(XSTypeDefinition type) {
+        assertEquals("Type is supposed to be anyType", SchemaGrammar.fAnyType,
+                type);
+    }
+
+    void assertEquals(String msg, Object expected, Object actual) {
+        if (!expected.equals(actual)) {
+            fail(msg + " Expected: " + expected + " Actual: " + actual);
+        } else {
+            success(null);
+        }
+    }
+    void assertNull(String msg, Object value) {
+        if (value != null) {
+            fail(msg);
+        } else {
+            success(null);
+        }
+    }
+    void assertTrue(String msg, boolean value) {
+        if (!value) {
+            fail(msg);
+        } else {
+            success(null);
+        }
+    }
+    void assertFalse(String msg, boolean value) {
+        if (value) {
+            fail(msg);
+        } else {
+            success(null);
+        }
+    }
+    void fail(String errMsg) {
+        if (errMessage == null) {
+            errMessage = errMsg;
+        } else {
+            errMessage = errMessage + "\n" + errMsg;
+        }
+        failed++;
+    }
+
+    void success(String msg) {
+        passed++;
+        System.out.println(msg);
+        if (msg != null) {
+            if (msg.length() != 0) {
+                System.out.println(msg);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/BasicTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class BasicTest extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "base.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public BasicTest(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testSimpleValidation() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+        doValidityAsserts();
+    }
+
+    @Test
+    public void testSimpleValidationWithTrivialXSIType() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(
+                "http://www.w3.org/2001/XMLSchema-instance", "type", "X");
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+        doValidityAsserts();
+    }
+
+    private void doValidityAsserts() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertElementNamespaceNull(fRootNode.getElementDeclaration()
+                .getNamespace());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/FixedAttrTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * The purpose of this test is to execute all of the isComparable calls in
+ * XMLSchemaValidator. There are two calls in processElementContent and two
+ * calls in processOneAttribute.
+ *
+ * @author peterjm
+ */
+public class FixedAttrTest extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "fixedAttr.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public FixedAttrTest(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefault() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("B", child.getElementDeclaration().getName());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("D", child.getElementDeclaration().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IdIdrefCheckingTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.xml.sax.SAXException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+// duplicate IDs
+// reference to non-existent ID
+
+public class IdIdrefCheckingTest extends BaseTest {
+    public static final String DUPLICATE_ID = "cvc-id.2";
+
+    public static final String NO_ID_BINDING = "cvc-id.1";
+
+    protected String getXMLDocument() {
+        return "idIdref.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] { DUPLICATE_ID, NO_ID_BINDING };
+    }
+
+    public IdIdrefCheckingTest(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefault() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSetFalse() {
+        try {
+            reset();
+            fValidator.setFeature(ID_IDREF_CHECKING, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkValidResult();
+    }
+
+    @Test
+    public void testSetTrue() {
+        try {
+            reset();
+            fValidator.setFeature(ID_IDREF_CHECKING, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    private void checkDefault() {
+        assertError(DUPLICATE_ID);
+        assertError(NO_ID_BINDING);
+
+        assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idType", child.getTypeDefinition().getName());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idType", child.getTypeDefinition().getName());
+
+        child = super.getChild(3);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idrefType", child.getTypeDefinition().getName());
+    }
+
+    private void checkValidResult() {
+        assertNoError(DUPLICATE_ID);
+        assertNoError(NO_ID_BINDING);
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idType", child.getTypeDefinition().getName());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idType", child.getTypeDefinition().getName());
+
+        child = super.getChild(3);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("idrefType", child.getTypeDefinition().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IdentityConstraintCheckingTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.xml.sax.SAXException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IdentityConstraintCheckingTest extends BaseTest {
+    // These values are unstable, since they're not actually error keys, but
+    // simply
+    // the first part of the error message.
+    public static final String DUPLICATE_UNIQUE = "cvc-identity-constraint.4.1";
+
+    public static final String DUPLICATE_KEY = "cvc-identity-constraint.4.2.2";
+
+    public static final String INVALID_KEYREF = "cvc-identity-constraint.4.3";
+
+    protected String getXMLDocument() {
+        return "idc.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "idc.xsd";
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] { DUPLICATE_UNIQUE, DUPLICATE_KEY, INVALID_KEYREF };
+    }
+
+    public IdentityConstraintCheckingTest(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefault() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSetFalse() {
+        try {
+            reset();
+            fValidator.setFeature(IDC_CHECKING, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkValidResult();
+    }
+
+    @Test
+    public void testSetTrue() {
+        try {
+            reset();
+            fValidator.setFeature(IDC_CHECKING, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    private void checkDefault() {
+        assertError(DUPLICATE_UNIQUE);
+        assertError(DUPLICATE_KEY);
+        assertError(INVALID_KEYREF);
+
+        assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("itemList", fRootNode.getElementDeclaration()
+                .getName());
+        assertTypeName("itemListType", fRootNode.getTypeDefinition().getName());
+
+        // this one is valid because it's the first one to define the unique
+        // value
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        // invalid because it repeats the unique value
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        // invalid because it repeats the key
+        child = super.getChild(3);
+        assertValidity(ItemPSVI.VALIDITY_INVALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        // valid because key references aren't figured out until the validation
+        // root
+        child = super.getChild(4);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("itemRef", child.getElementDeclaration().getName());
+        assertTypeName("string", child.getTypeDefinition().getName());
+    }
+
+    private void checkValidResult() {
+        assertNoError(DUPLICATE_UNIQUE);
+        assertNoError(DUPLICATE_KEY);
+        assertNoError(INVALID_KEYREF);
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("itemList", fRootNode.getElementDeclaration()
+                .getName());
+        assertTypeName("itemListType", fRootNode.getTypeDefinition().getName());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        child = super.getChild(3);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("item", child.getElementDeclaration().getName());
+        assertTypeName("itemType", child.getTypeDefinition().getName());
+
+        child = super.getChild(4);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("itemRef", child.getElementDeclaration().getName());
+        assertTypeName("string", child.getTypeDefinition().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_A.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_A_A extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_A_A.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_A_A(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        checkResult();
+    }
+
+    private void checkFalseResult() {
+        checkResult();
+    }
+
+    private void checkResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_A_C.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_A_C extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_A_C.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_A_C(String name) {
+        super(name);
+    }
+
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        checkResult();
+    }
+
+    private void checkFalseResult() {
+        checkResult();
+    }
+
+    private void checkResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_A.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_C_A extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_C_A.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_C_A(String name) {
+        super(name);
+    }
+
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertAnyType(fRootNode.getTypeDefinition());
+
+        checkChild();
+    }
+
+    private void checkFalseResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        checkChild();
+    }
+
+    private void checkChild() {
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_AC.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_C_AC extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_C_AC.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_C_AC(String name) {
+        super(name);
+    }
+
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertAnyType(fRootNode.getTypeDefinition());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertAnyType(child.getTypeDefinition());
+    }
+
+    private void checkFalseResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_C.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_C_C extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_C_C.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_C_C(String name) {
+        super(name);
+    }
+
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertAnyType(fRootNode.getTypeDefinition());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertAnyType(child.getTypeDefinition());
+    }
+
+    private void checkFalseResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/IgnoreXSITypeTest_C_CA.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class IgnoreXSITypeTest_C_CA extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "xsitype_C_CA.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    public IgnoreXSITypeTest_C_CA(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultDocument() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testDefaultFragment() {
+        try {
+            reset();
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        // default value of the feature is false
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetFalseFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, false);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkFalseResult();
+    }
+
+    @Test
+    public void testSetTrueDocument() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    @Test
+    public void testSetTrueFragment() {
+        try {
+            reset();
+            fValidator.setFeature(IGNORE_XSI_TYPE, true);
+            validateFragment();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkTrueResult();
+    }
+
+    private void checkTrueResult() {
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_PARTIAL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertAnyType(fRootNode.getTypeDefinition());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_NONE, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertAnyType(child.getTypeDefinition());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+
+    private void checkFalseResult() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
+
+        PSVIElementNSImpl child = super.getChild(1);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementNull(child.getElementDeclaration());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+
+        child = super.getChild(2);
+        assertValidity(ItemPSVI.VALIDITY_VALID, child.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, child
+                .getValidationAttempted());
+        assertElementName("A", child.getElementDeclaration().getName());
+        assertTypeName("Y", child.getTypeDefinition().getName());
+        assertTypeNamespaceNull(child.getTypeDefinition().getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/RootTypeDefinitionTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import javax.xml.namespace.QName;
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class RootTypeDefinitionTest extends BaseTest {
+    private QName unknownType;
+
+    private QName typeX;
+
+    private QName typeY;
+
+    private QName typeZ;
+
+    private QName typeOtherNamespace;
+
+    private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1";
+
+    private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3";
+
+    protected String getXMLDocument() {
+        return "base.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR };
+    }
+
+    public RootTypeDefinitionTest(String name) {
+        super(name);
+        unknownType = new QName("W");
+        typeX = new QName("X");
+        typeY = new QName("Y");
+        typeZ = new QName("Z");
+        typeOtherNamespace = new QName("xslt.unittests", "W", "unit");
+    }
+
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefault() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSettingNull() {
+        try {
+            reset();
+            fValidator.setProperty(ROOT_TYPE, null);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSettingToUnknownType() {
+        try {
+            reset();
+            fValidator.setProperty(ROOT_TYPE, unknownType);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertError(UNKNOWN_TYPE_ERROR);
+        checkDefault();
+    }
+
+    @Test
+    public void testSettingToEqualType() {
+        try {
+            reset();
+            fValidator.setProperty(ROOT_TYPE, typeX);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+    }
+
+    @Test
+    public void testSettingToDerivedType() {
+        try {
+            reset();
+            // this is required to make it a valid type Y node
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY");
+            fValidator.setProperty(ROOT_TYPE, typeY);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+    }
+
+    @Test
+    public void testSettingToNonDerivedType() {
+        try {
+            reset();
+            fValidator.setProperty(ROOT_TYPE, typeZ);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Z", fRootNode.getTypeDefinition().getName());
+    }
+
+    @Test
+    public void testSettingToOtherSchemaType() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI,
+                SchemaSymbols.XSI_SCHEMALOCATION,
+                "xslt.unittests otherNamespace.xsd");
+            fValidator.setProperty(ROOT_TYPE, typeOtherNamespace);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("W", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition()
+                .getNamespace());
+    }
+
+    @Test
+    public void testSettingTypeAndXSIType() {
+        try {
+            reset();
+            // this is required to make it a valid type Y node
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(null, "attr", "typeY");
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI,
+                    SchemaSymbols.XSI_TYPE, "Y");
+            fValidator.setProperty(ROOT_TYPE, typeX);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Y", fRootNode.getTypeDefinition().getName());
+    }
+
+    @Test
+    public void testSettingTypeAndInvalidXSIType() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(SchemaSymbols.URI_XSI,
+                    SchemaSymbols.XSI_TYPE, "Z");
+            fValidator.setProperty(ROOT_TYPE, typeX);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertError(INVALID_DERIVATION_ERROR);
+        assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertTypeName("Z", fRootNode.getTypeDefinition().getName());
+    }
+
+    private void checkDefault() {
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/SpecialCaseErrorHandler.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+public class SpecialCaseErrorHandler implements ErrorHandler {
+    public static final boolean DEBUG = false;
+
+    private HashMap<String, Boolean> errors;
+
+    public SpecialCaseErrorHandler(String[] specialCases) {
+        errors = new HashMap<>();
+        for (int i = 0; i < specialCases.length; ++i) {
+            errors.put(specialCases[i], Boolean.FALSE);
+        }
+    }
+
+    public void reset() {
+        errors.keySet().stream().forEach((error) -> {
+            errors.put(error, Boolean.FALSE);
+        });
+    }
+
+    @Override
+    public void warning(SAXParseException arg0) throws SAXException {
+        if (DEBUG) {
+            System.err.println(arg0.getMessage());
+        }
+    }
+
+    @Override
+    public void error(SAXParseException arg0) throws SAXException {
+        if (DEBUG) {
+            System.err.println(arg0.getMessage());
+        }
+        errors.keySet().stream().filter((error) -> (arg0.getMessage().startsWith(error))).forEach((error) -> {
+            errors.put(error, Boolean.TRUE);
+        });
+    }
+
+    public void fatalError(SAXParseException arg0) throws SAXException {
+        throw arg0;
+    }
+
+    public boolean specialCaseFound(String key) {
+        return ((Boolean) errors.get(key)).booleanValue();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/TEST.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+# This file identifies root(s) of the test-ng hierarchy.
+
+TestNG.dirs = .
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/UnparsedEntityCheckingTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class UnparsedEntityCheckingTest extends BaseTest {
+    public static final String UNDECLARED_ENTITY = "UndeclaredEntity";
+
+    protected String getXMLDocument() {
+        return "unparsedEntity.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] { UNDECLARED_ENTITY };
+    }
+
+    public UnparsedEntityCheckingTest(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testDefaultValid() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSetFalseValid() {
+        try {
+            reset();
+            fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSetTrueValid() {
+        try {
+            reset();
+            fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testDefaultInvalid() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(null,
+                    "unparsedEntityAttr", "invalid");
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkInvalid();
+    }
+
+    @Test
+    public void testSetFalseInvalid() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(null,
+                    "unparsedEntityAttr", "invalid");
+            fValidator.setFeature(UNPARSED_ENTITY_CHECKING, false);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkDefault();
+    }
+
+    @Test
+    public void testSetTrueInvalid() {
+        try {
+            reset();
+            ((PSVIElementNSImpl) fRootNode).setAttributeNS(null,
+                    "unparsedEntityAttr", "invalid");
+            fValidator.setFeature(UNPARSED_ENTITY_CHECKING, true);
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        checkInvalid();
+    }
+
+    private void checkDefault() {
+        assertNoError(UNDECLARED_ENTITY);
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+    }
+
+    private void checkInvalid() {
+        assertError(UNDECLARED_ENTITY);
+        assertValidity(ItemPSVI.VALIDITY_INVALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertTypeName("X", fRootNode.getTypeDefinition().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_False.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class UseGrammarPoolOnlyTest_False extends BaseTest {
+    private final static String UNKNOWN_TYPE_ERROR = "cvc-type.1";
+
+    private final static String INVALID_DERIVATION_ERROR = "cvc-elt.4.3";
+
+    protected String getXMLDocument() {
+        return "otherNamespace.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    protected String[] getRelevantErrorIDs() {
+        return new String[] { UNKNOWN_TYPE_ERROR, INVALID_DERIVATION_ERROR };
+    }
+
+    protected boolean getUseGrammarPoolOnly() {
+        return false;
+    }
+
+    public UseGrammarPoolOnlyTest_False(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY
+     * feature to true causes external schemas to not be read. This
+     * functionality already existed prior to adding the XSLT 2.0 validation
+     * features; however, because the class that controlled it changed, this
+     * test simply ensures that the existing functionality did not disappear.
+     * -PM
+     */
+    @Test
+    public void testUsingOnlyGrammarPool() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
+                .getValidationAttempted());
+        assertElementName("A", fRootNode.getElementDeclaration().getName());
+        assertElementNamespace("xslt.unittests", fRootNode
+                .getElementDeclaration().getNamespace());
+        assertTypeName("W", fRootNode.getTypeDefinition().getName());
+        assertTypeNamespace("xslt.unittests", fRootNode.getTypeDefinition()
+                .getNamespace());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/UseGrammarPoolOnlyTest_True.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class UseGrammarPoolOnlyTest_True extends BaseTest {
+
+    protected String getXMLDocument() {
+        return "otherNamespace.xml";
+    }
+
+    protected String getSchemaFile() {
+        return "base.xsd";
+    }
+
+    protected boolean getUseGrammarPoolOnly() {
+        return true;
+    }
+
+    public UseGrammarPoolOnlyTest_True(String name) {
+        super(name);
+    }
+
+    @BeforeClass
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @AfterClass
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * The purpose of this test is to check if setting the USE_GRAMMAR_POOL_ONLY
+     * feature to true causes external schemas to not be read. This
+     * functionality already existed prior to adding the XSLT 2.0 validation
+     * features; however, because the class that controlled it changed, this
+     * test simply ensures that the existing functionality did not disappear.
+     * -PM
+     */
+    @Test
+    public void testUsingOnlyGrammarPool() {
+        try {
+            reset();
+            validateDocument();
+        } catch (Exception e) {
+            fail("Validation failed: " + e.getMessage());
+        }
+
+        assertValidity(ItemPSVI.VALIDITY_NOTKNOWN, fRootNode.getValidity());
+        assertValidationAttempted(ItemPSVI.VALIDATION_NONE, fRootNode
+                .getValidationAttempted());
+        assertElementNull(fRootNode.getElementDeclaration());
+        assertAnyType(fRootNode.getTypeDefinition());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<A attr="typeX">
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/base.xsd	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,74 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+  <xsd:element name="A" type="X"/>
+
+  <!-- The purpose of this element is:
+       a) To have a fixed attribute use
+       b) To have an attribute with a fixed attribute declaration
+       c) To have a complex type with simple content and a fixed value
+       d) To have an element declaration with a fixed value
+   -->
+  <xsd:element name="B" fixed="howdy">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute ref="fixedAttr" use="required" fixed="hello"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  
+  <xsd:element name="D" type="xsd:string" fixed="hey"/>
+
+  <xsd:attribute name="attr" type="xsd:string"/>
+
+  <xsd:attribute name="unparsedEntityAttr" type="xsd:ENTITIES"/>
+
+  <xsd:attribute name="fixedAttr" type="xsd:string" fixed="hello"/>
+
+  <xsd:complexType name="X">
+    <xsd:sequence>
+      <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute ref="attr"/>
+    <xsd:attribute ref="unparsedEntityAttr"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="Y">
+    <xsd:complexContent>
+	    <xsd:restriction base="X">
+		    <xsd:sequence>
+		      <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+		    </xsd:sequence>
+		    <xsd:attribute ref="attr" fixed="typeY"/>
+		    <xsd:attribute ref="unparsedEntityAttr" use="prohibited"/>
+	    </xsd:restriction>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <!-- Z is the same as X, but is not derived from X. -->
+  <xsd:complexType name="Z">
+    <xsd:sequence>
+      <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute ref="attr"/>
+    <xsd:attribute ref="unparsedEntityAttr"/>
+  </xsd:complexType>
+  
+  <xsd:complexType name="idType">
+    <xsd:complexContent>
+	    <xsd:extension base="X">
+		    <xsd:attribute name="idAttr" type="xsd:ID"/>
+	    </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="idrefType">
+    <xsd:complexContent>
+	    <xsd:extension base="X">
+		    <xsd:attribute name="idrefAttr" type="xsd:IDREF"/>
+	    </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+</xsd:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/fixedAttr.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<A>
+  <B fixedAttr="hello">howdy</B>
+  <D>hey</D>
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/idIdref.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <A xsi:type="idType" idAttr="ONE"/>
+   <A xsi:type="idType" idAttr="ONE"/>
+   <A xsi:type="idrefType" idrefAttr="TWO"/>
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<itemList>
+   <item uniqueAttr="ONE">1</item>
+   <item uniqueAttr="ONE">2</item>
+   <item uniqueAttr="TWO">2</item>
+   <itemRef>3</itemRef>
+</itemList>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/idc.xsd	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,41 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+  <xsd:element name="itemList" type="itemListType">
+    <xsd:unique name="itemAttr">
+      <xsd:selector xpath="item"/>
+      <xsd:field    xpath="@uniqueAttr"/>
+    </xsd:unique>
+
+    <xsd:key name="itemValueKey">
+      <xsd:selector xpath="item"/>
+      <xsd:field    xpath="."/>
+    </xsd:key>
+
+    <xsd:keyref name="itemKeyRef" refer="itemValueKey">
+      <xsd:selector xpath="itemRef"/>
+      <xsd:field    xpath="."/>
+    </xsd:keyref>
+  </xsd:element>
+  
+  <xsd:element name="item" type="itemType"/>
+
+  <xsd:attribute name="uniqueAttr" type="xsd:string"/>
+
+  <xsd:attribute name="unparsedEntityAttr" type="xsd:ENTITIES"/>
+
+  <xsd:complexType name="itemListType">
+    <xsd:sequence>
+      <xsd:element ref="item" maxOccurs="unbounded"/>
+      <xsd:element name="itemRef" type="xsd:string" maxOccurs="unbounded"/>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="itemType">
+    <xsd:simpleContent>
+      <xsd:extension base="xsd:string">
+        <xsd:attribute ref="uniqueAttr" use="required"/>
+      </xsd:extension>
+    </xsd:simpleContent>
+  </xsd:complexType>
+
+</xsd:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<unit:A xmlns:unit="xslt.unittests"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="xslt.unittests otherNamespace.xsd"
+        attr="typeX">
+</unit:A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/otherNamespace.xsd	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,18 @@
+<xsd:schema
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+  xmlns:unit="xslt.unittests"
+  targetNamespace="xslt.unittests">
+  
+  <xsd:import schemaLocation="base.xsd"/>
+  
+  <xsd:element name="A" type="unit:W"/>
+  
+  <xsd:complexType name="W">
+    <xsd:sequence>
+      <xsd:any processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute ref="attr"/>
+    <xsd:attribute ref="unparsedEntityAttr"/>
+  </xsd:complexType>
+
+</xsd:schema>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.dtd	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+<!NOTATION myNotation SYSTEM "somethingElse" >
+<!ENTITY myUnparsedEntity SYSTEM "something" NDATA myNotation >
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/unparsedEntity.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<!DOCTYPE personnel SYSTEM "unparsedEntity.dtd">
+<A attr="blah" unparsedEntityAttr="myUnparsedEntity">
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_A.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<A attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <A attr="typeY" xsi:type="Y"/>
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_A_C.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<A attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <C attr="typeY" xsi:type="Y"/>
+</A>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_A.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<C attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <A attr="typeY" xsi:type="Y"/>
+</C>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_AC.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<C attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <A attr="typeY" xsi:type="Y"/>
+   <C attr="typeY" xsi:type="Y"/>
+</C>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_C.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<C attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <C attr="typeY" xsi:type="Y"/>
+</C>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/testng/validation/8037819/xsitype_C_CA.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<C attr="typeY"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:type="Y">
+   <C attr="typeY" xsi:type="Y"/>
+   <A attr="typeY" xsi:type="Y"/>
+</C>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/JavaToolUtils.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/**
+ * Utils class for compiling , creating jar file and executing a java command
+ *
+ * @author Raghu Nair
+ */
+
+public class JavaToolUtils {
+
+    public static final long DEFAULT_WAIT_TIME = 10000;
+
+    private JavaToolUtils() {
+    }
+
+    /**
+     * Takes a list of files and compile these files into the working directory.
+     *
+     * @param files
+     * @throws IOException
+     */
+    public static void compileFiles(List<File> files) throws IOException {
+        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+        try (StandardJavaFileManager fileManager = compiler.
+                getStandardFileManager(null, null, null)) {
+            Iterable<? extends JavaFileObject> compilationUnit
+                    = fileManager.getJavaFileObjectsFromFiles(files);
+            compiler.getTask(null, fileManager, null, null, null,
+                    compilationUnit).call();
+        }
+    }
+
+    /**
+     * Create a jar file using the list of files provided.
+     *
+     * @param jar
+     * @param files
+     * @throws IOException
+     */
+    public static void createJar(File jar, List<File> files)
+            throws IOException {
+        Manifest manifest = new Manifest();
+        manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION,
+                "1.0");
+        try (JarOutputStream target = new JarOutputStream(
+                new FileOutputStream(jar), manifest)) {
+            for (File file : files) {
+                add(file, target);
+            }
+        }
+    }
+
+    private static void add(File source, JarOutputStream target)
+            throws IOException {
+        Objects.requireNonNull(source, "source cannot be null");
+        Objects.requireNonNull(target, "target cannot be null");
+        // not tested against directories and from different path.
+        String name = source.getName();
+        if (source.isDirectory()) {
+            if (!name.isEmpty()) {
+                if (!name.endsWith("/")) {
+                    name += "/";
+                }
+                JarEntry entry = new JarEntry(name);
+                entry.setTime(source.lastModified());
+                target.putNextEntry(entry);
+                target.closeEntry();
+            }
+            for (File nestedFile : source.listFiles()) {
+                add(nestedFile, target);
+            }
+            return;
+        }
+        System.out.println("Adding entry " + name);
+        JarEntry entry = new JarEntry(name);
+        entry.setTime(source.lastModified());
+        target.putNextEntry(entry);
+        Files.copy(source.toPath(), target);
+        target.closeEntry();
+    }
+
+    /**
+     * Runs java command with provided arguments. Caller should not pass java
+     * command in the argument list.
+     *
+     * @param commands
+     * @param waitTime time to wait for the command to exit in milli seconds
+     * @return
+     * @throws Exception
+     */
+    public static int runJava(List<String> commands,long waitTime)
+            throws Exception {
+        String java = System.getProperty("java.home") + "/bin/java";
+        commands.add(0, java);
+        String command = commands.toString().replace(",", " ");
+        System.out.println("Executing the following command \n" + command);
+        ProcessBuilder processBuilder = new ProcessBuilder(commands);
+        final Process process = processBuilder.start();
+        BufferedReader errorStream = new BufferedReader(
+                new InputStreamReader(process.getErrorStream()));
+        BufferedReader outStream = new BufferedReader(
+                new InputStreamReader(process.getInputStream()));
+        String errorLine;
+        StringBuilder errors = new StringBuilder();
+        String outLines;
+        while ((errorLine = errorStream.readLine()) != null) {
+            errors.append(errorLine).append("\n");
+        }
+        while ((outLines = outStream.readLine()) != null) {
+            System.out.println(outLines);
+        }
+        errorLine = errors.toString();
+        System.err.println(errorLine);
+        process.waitFor(waitTime, TimeUnit.MILLISECONDS);
+        int exitStatus = process.exitValue();
+        if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) {
+            throw new RuntimeException(errorLine);
+        }
+        return exitStatus;
+    }
+
+    /**
+     * Runs java command with provided arguments. Caller should not pass java
+     * command in the argument list.
+     *
+     * @param commands
+     * @return
+     * @throws Exception
+     */
+    public static int runJava(List<String> commands) throws Exception {
+        return runJava(commands, DEFAULT_WAIT_TIME);
+    }
+
+    /**
+     * Run any command
+     * @param commands
+     * @return
+     * @throws Exception
+     */
+    public static int runCommand(List<String> commands) throws Exception {
+        String command = commands.toString().replace(",", " ");
+        System.out.println("Executing the following command \n" + command);
+        ProcessBuilder processBuilder = new ProcessBuilder(commands);
+        final Process process = processBuilder.start();
+        BufferedReader errorStream = new BufferedReader(
+                new InputStreamReader(process.getErrorStream()));
+        BufferedReader outStream = new BufferedReader(
+                new InputStreamReader(process.getInputStream()));
+        String errorLine;
+        StringBuilder errors = new StringBuilder();
+        String outLines;
+        while ((errorLine = errorStream.readLine()) != null) {
+            errors.append(errorLine).append("\n");
+        }
+        while ((outLines = outStream.readLine()) != null) {
+            System.out.println(outLines);
+        }
+        errorLine = errors.toString();
+        System.err.println(errorLine);
+        int exitStatus = process.exitValue();
+        if (exitStatus != 0 && errorLine != null && errorLine.isEmpty()) {
+            throw new RuntimeException(errorLine);
+        }
+        return exitStatus;
+    }
+
+
+}
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,7 +26,7 @@
 import java.lang.reflect.Method;
 import java.net.ConnectException;
 import java.net.ServerSocket;
-import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 import java.util.ArrayList;
@@ -174,9 +174,9 @@
         } catch (Exception e) {
             Throwable t = e;
             while (t != null) {
-                if (t instanceof NoSuchObjectException ||
-                    t instanceof ConnectException ||
-                    t instanceof SSLHandshakeException) {
+                if (t instanceof RemoteException ||
+                    t instanceof SSLHandshakeException ||
+                    t instanceof ConnectException) {
                     break;
                 }
                 t = t.getCause();
@@ -617,7 +617,10 @@
                 busyPort = ss.getLocalPort();
                 jcmd(
                     line -> {
-                        if (line.contains("Port already in use: " + busyPort)) {
+                        boolean match = line.contains("Port already in use: " +
+                                                      busyPort);
+                        System.out.println("[match] " + line + " => "  + match);
+                        if (match) {
                             checks.getAndUpdate((op) -> op | 4);
                         }
                     },
--- a/jdk/test/sun/text/resources/LocaleData	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/sun/text/resources/LocaleData	Wed Jul 05 20:00:07 2017 +0200
@@ -7696,3 +7696,6 @@
 # bug 8037343
 FormatData/es_DO/DatePatterns/2=dd/MM/yyyy
 FormatData/es_DO/DatePatterns/3=dd/MM/yy
+
+# bug 8055222
+CurrencyNames/lt_LT/EUR=\u20AC
--- a/jdk/test/sun/text/resources/LocaleDataTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -36,7 +36,7 @@
  *      6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7101495
  *      7003124 7085757 7028073 7171028 7189611 8000983 7195759 8004489 8006509
  *      7114053 7074882 7040556 8013836 8021121 6192407 6931564 8027695 8017142
- *      8037343
+ *      8037343 8055222
  * @summary Verify locale data
  *
  */
--- a/jdk/test/sun/tools/jstatd/JstatdTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/jdk/test/sun/tools/jstatd/JstatdTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -148,11 +148,12 @@
     private OutputAnalyzer waitForJstatdRMI(ProcessBuilder pb) throws IOException, InterruptedException {
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
+        String remoteHost = (serverName != null) ? serverName : "JStatRemoteHost";
         while (output.getExitValue() != 0) {
             String out = output.getOutput();
 
             if (out.contains("RMI Registry not available") ||
-                out.contains("RMI Server JStatRemoteHost not available")) {
+                out.contains("RMI Server " + remoteHost + " not available")) {
                 Thread.sleep(100);
                 output = new OutputAnalyzer(pb.start());
             } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/locale/provider/Bug8038436.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2014, 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 8038436
+ * @summary Test for changes in 8038436
+ * @compile -XDignore.symbol.file Bug8038436.java
+ * @run main/othervm Bug8038436 -Djava.ext.dirs=foo security
+ * @run main/othervm Bug8038436 -Djava.locale.providers=JRE availlocs
+ */
+
+import java.security.*;
+import java.text.*;
+import java.util.*;
+import java.util.stream.*;
+import sun.util.locale.provider.*;
+
+public class Bug8038436 {
+    public static void main(String[] args) {
+        switch (args[1]) {
+        case "security":
+            securityTests();
+            break;
+        case "availlocs":
+            availableLocalesTests();
+            break;
+        default:
+            throw new RuntimeException("no test was specified.");
+        }
+    }
+
+    private static void securityTests() {
+        Policy.setPolicy(new MyPolicy());
+        System.setSecurityManager(new SecurityManager());
+
+        /*
+         * Test for AccessClassInPackage security exception. Confirms that
+         * exeption won't be thrown if an application sets a Permission that
+         * does not allow any RuntimePermission, on loading LocaleDataMetaInfo
+         * from jdk.localedata module.
+         */
+        System.out.println(new Formatter(Locale.JAPAN).format("%1$tB %1$te, %1$tY",
+                           new GregorianCalendar()));
+
+        /*
+         * Check only English/ROOT locales are returned if the jdk.localedata
+         * module is not installed (implied by "java.ext.dirs" set to "foo").
+         */
+        if (Arrays.asList(Locale.getAvailableLocales())
+                .stream()
+                .anyMatch(l -> l != Locale.ROOT && l.getLanguage() != "en")) {
+            throw new RuntimeException("non English locale(s) included in available locales");
+        }
+    }
+
+
+    static class MyPolicy extends Policy {
+        final PermissionCollection perms = new Permissions();
+
+        MyPolicy() {
+            // allows no RuntimePermission
+        }
+
+        public PermissionCollection getPermissions(ProtectionDomain domain) {
+            return perms;
+        }
+
+        public PermissionCollection getPermissions(CodeSource codesource) {
+            return perms;
+        }
+
+        public boolean implies(ProtectionDomain domain, Permission perm) {
+            return perms.implies(perm);
+        }
+    }
+
+    static final String[] bipLocs = ("ar, ar-JO, ar-LB, ar-SY, be, be-BY, bg, " +
+        "bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, de, de-AT, de-CH, de-DE, " +
+        "de-LU, el, el-CY, el-GR, en, en-AU, en-CA, en-GB, en-IE, en-IN, " +
+        "en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " +
+        "es-CO, es-CR, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " +
+        "es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et, et-EE, " +
+        "fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, ga, ga-IE, he, he-IL, " +
+        "hi-IN, hr, hr-HR, hu, hu-HU, id, id-ID, is, is-IS, it, it-CH, it-IT, " +
+        "ja, ja-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, mk, mk-MK, ms, ms-MY, mt, " +
+        "mt-MT, nl, nl-BE, nl-NL, no, no-NO, no-NO, pl, pl-PL, pt, pt-BR, " +
+        "pt-PT, ro, ro-RO, ru, ru-RU, sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, " +
+        "sr-BA, sr-CS, sr-Latn, sr-Latn-ME, sr-ME, sr-RS, sv, sv-SE, th, th-TH, " +
+        "tr, tr-TR, uk, uk-UA, und, vi, vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, " +
+        "zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
+    static final String[] dfpLocs = bipLocs;
+    static final String[] datefspLocs = bipLocs;
+    static final String[] decimalfspLocs = bipLocs;
+    static final String[] calnpLocs = bipLocs;
+    static final String[] cpLocs = ("ar, be, bg, ca, cs, da, el, es, et, fi, " +
+        "fr, he, hi, hr, hu, is, ja, ko, lt, lv, mk, no, pl, ro, ru, sk, sl, " +
+        "sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, zh-HK, zh-Hant-HK, " +
+        "zh-Hant-TW, zh-TW, ").split(",\\s*");
+    static final String[] nfpLocs = ("ar, ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
+        "ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " +
+        "ar-TN, ar-YE, be, be-BY, bg, bg-BG, ca, ca-ES, cs, cs-CZ, da, da-DK, " +
+        "de, de-AT, de-CH, de-DE, de-GR, de-LU, el, el-CY, el-GR, en, en-AU, " +
+        "en-CA, en-GB, en-IE, en-IN, en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, " +
+        "es, es-AR, es-BO, es-CL, es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, " +
+        "es-GT, es-HN, es-MX, es-NI, es-PA, es-PE, es-PR, es-PY, es-SV, es-US, " +
+        "es-UY, es-VE, et, et-EE, fi, fi-FI, fr, fr-BE, fr-CA, fr-CH, fr-FR, " +
+        "fr-LU, ga, ga-IE, he, he-IL, hi, hi-IN, hr, hr-HR, hu, hu-HU, id, " +
+        "id-ID, is, is-IS, it, it-CH, it-IT, ja, ja-JP, " +
+        "ja-JP-u-ca-japanese-x-lvariant-JP, ko, ko-KR, lt, lt-LT, lv, lv-LV, " +
+        "mk, mk-MK, ms, ms-MY, mt, mt-MT, nb-NO, nl, nl-BE, nl-NL, nn-NO, " +
+        "nn-NO, no, no-NO, pl, pl-PL, pt, pt-BR, pt-PT, ro, ro-RO, ru, ru-RU, " +
+        "sk, sk-SK, sl, sl-SI, sq, sq-AL, sr, sr-BA, sr-CS, sr-Latn, " +
+        "sr-Latn-BA, sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th, " +
+        "th-TH, th-TH-u-nu-thai-x-lvariant-TH, tr, tr-TR, uk, uk-UA, und, vi, " +
+        "vi-VN, zh, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
+        "zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
+    static final String[] currencynpLocs = ("ar-AE, ar-BH, ar-DZ, ar-EG, ar-IQ, " +
+        "ar-JO, ar-KW, ar-LB, ar-LY, ar-MA, ar-OM, ar-QA, ar-SA, ar-SD, ar-SY, " +
+        "ar-TN, ar-YE, be-BY, bg-BG, ca-ES, cs-CZ, da-DK, de, de-AT, de-CH, " +
+        "de-DE, de-GR, de-LU, el-CY, el-GR, en-AU, en-CA, en-GB, en-IE, en-IN, " +
+        "en-MT, en-NZ, en-PH, en-SG, en-US, en-ZA, es, es-AR, es-BO, es-CL, " +
+        "es-CO, es-CR, es-CU, es-DO, es-EC, es-ES, es-GT, es-HN, es-MX, es-NI, " +
+        "es-PA, es-PE, es-PR, es-PY, es-SV, es-US, es-UY, es-VE, et-EE, fi-FI, " +
+        "fr, fr-BE, fr-CA, fr-CH, fr-FR, fr-LU, ga-IE, he-IL, hi-IN, hr-HR, " +
+        "hu-HU, id-ID, is-IS, it, it-CH, it-IT, ja, ja-JP, ko, ko-KR, lt-LT, " +
+        "lv-LV, mk-MK, ms-MY, mt-MT, nl-BE, nl-NL, no-NO, pl-PL, pt, pt-BR, " +
+        "pt-PT, ro-RO, ru-RU, sk-SK, sl-SI, sq-AL, sr-BA, sr-CS, sr-Latn-BA, " +
+        "sr-Latn-ME, sr-Latn-RS, sr-ME, sr-RS, sv, sv-SE, th-TH, tr-TR, uk-UA, " +
+        "und, vi-VN, zh-CN, zh-HK, zh-Hans-CN, zh-Hans-SG, zh-Hant-HK, " +
+        "zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
+    static final String[] lnpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
+        "en, en-MT, en-PH, en-SG, es, es-US, et, fi, fr, ga, he, hi, hr, hu, " +
+        "id, is, it, ja, ko, lt, lv, mk, ms, mt, nl, no, no-NO, pl, pt, pt-BR, " +
+        "pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn, sv, th, tr, uk, und, vi, zh, " +
+        "zh-HK, zh-Hans-SG, zh-Hant-HK, zh-Hant-TW, zh-SG, zh-TW, ").split(",\\s*");
+    static final String[] tznpLocs = ("de, en, en-CA, en-GB, en-IE, es, fr, hi, " +
+        "it, ja, ko, pt-BR, sv, und, zh-CN, zh-HK, zh-Hans-CN, zh-Hant-HK, " +
+        "zh-Hant-TW, zh-TW, ").split(",\\s*");
+    static final String[] caldpLocs = ("ar, be, bg, ca, cs, da, de, el, el-CY, " +
+        "en, en-GB, en-IE, en-MT, es, es-ES, es-US, et, fi, fr, fr-CA, he, hi, " +
+        "hr, hu, id-ID, is, it, ja, ko, lt, lv, mk, ms-MY, mt, mt-MT, nl, no, " +
+        "pl, pt, pt-BR, pt-PT, ro, ru, sk, sl, sq, sr, sr-Latn-BA, sr-Latn-ME, " +
+        "sr-Latn-RS, sv, th, tr, uk, und, vi, zh, ").split(",\\s*");
+    static final String[] calpLocs = caldpLocs;
+
+    /*
+     * Validate whether JRE's *Providers return supported locales list based on
+     * their actual resource bundle exsistence. The above golden data
+     * are manually extracted, so they need to be updated if new locale
+     * data resource bundle were added.
+     */
+    private static void availableLocalesTests() {
+        LocaleProviderAdapter jre = LocaleProviderAdapter.forJRE();
+
+        checkAvailableLocales("BreakIteratorProvider",
+            jre.getBreakIteratorProvider().getAvailableLocales(), bipLocs);
+        checkAvailableLocales("CollatorProvider",
+            jre.getCollatorProvider().getAvailableLocales(), cpLocs);
+        checkAvailableLocales("DateFormatProvider",
+            jre.getDateFormatProvider().getAvailableLocales(), dfpLocs);
+        checkAvailableLocales("DateFormatSymbolsProvider",
+            jre.getDateFormatSymbolsProvider().getAvailableLocales(), datefspLocs);
+        checkAvailableLocales("DecimalFormatSymbolsProvider",
+            jre.getDecimalFormatSymbolsProvider().getAvailableLocales(), decimalfspLocs);
+        checkAvailableLocales("NumberFormatProvider",
+            jre.getNumberFormatProvider().getAvailableLocales(), nfpLocs);
+        checkAvailableLocales("CurrencyNameProvider",
+            jre.getCurrencyNameProvider().getAvailableLocales(), currencynpLocs);
+        checkAvailableLocales("LocaleNameProvider",
+            jre.getLocaleNameProvider().getAvailableLocales(), lnpLocs);
+        checkAvailableLocales("TimeZoneNameProvider",
+            jre.getTimeZoneNameProvider().getAvailableLocales(), tznpLocs);
+        checkAvailableLocales("CalendarDataProvider",
+            jre.getCalendarDataProvider().getAvailableLocales(), caldpLocs);
+        checkAvailableLocales("CalendarNameProvider",
+            jre.getCalendarNameProvider().getAvailableLocales(), calnpLocs);
+        checkAvailableLocales("CalendarProvider",
+            jre.getCalendarProvider().getAvailableLocales(), calpLocs);
+    }
+
+    private static void checkAvailableLocales(String testName, Locale[] got, String[] expected) {
+        System.out.println("Testing available locales for " + testName);
+        List<Locale> gotList = Arrays.asList(got).stream()
+            .map(Locale::toLanguageTag)
+            .sorted()
+            .map(Locale::forLanguageTag)
+            .collect(Collectors.toList());
+        List<Locale> expectedList = Arrays.asList(expected).stream()
+            .map(Locale::forLanguageTag)
+            .collect(Collectors.toList());
+
+        if (!gotList.equals(expectedList)) {
+            throw new RuntimeException("\n" + gotList.toString() + "\n is not equal to \n" +
+                                       expectedList.toString());
+        }
+    }
+}
--- a/langtools/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -271,3 +271,4 @@
 5b20a93f8db0b87b902bde48bb7cbb05e88e6e9c jdk9-b26
 10fc81ac75b445528851c9e46c6eeb4438d4e363 jdk9-b27
 016786f793149135ab6b23c71087c1ca12691d77 jdk9-b28
+13705e2ddeb20a78e066595a1709e61f257189e9 jdk9-b29
--- a/langtools/make/intellij/codeStyleSettings.xml	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/make/intellij/codeStyleSettings.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -3,6 +3,7 @@
   <component name="ProjectCodeStyleSettingsManager">
     <option name="PER_PROJECT_SETTINGS">
       <value>
+        <option name="INSERT_INNER_CLASS_IMPORTS" value="true" />
         <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
         <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="999" />
         <option name="RIGHT_MARGIN" value="100" />
--- a/langtools/make/intellij/copyright/profiles_settings.xml	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/make/intellij/copyright/profiles_settings.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -1,3 +1,7 @@
 <component name="CopyrightManager">
-  <settings default="langtools" />
-</component>
\ No newline at end of file
+  <settings default="langtools">
+    <LanguageOptions name="JAVA">
+      <option name="fileLocation" value="1" />
+    </LanguageOptions>
+  </settings>
+</component>
--- a/langtools/make/intellij/workspace.xml	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/make/intellij/workspace.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -142,6 +142,9 @@
       <method />
     </configuration>
   </component>
+  <component name="StructureViewFactory">
+    <option name="ACTIVE_ACTIONS" value=",ALPHA_COMPARATOR" />
+  </component>
   <component name="antWorkspaceConfiguration">
     <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
     <option name="FILTER_TARGETS" value="false" />
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/AttributeWriter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -297,17 +297,18 @@
                     writeInnerClassHeader();
                     first = false;
                 }
-                print("   ");
                 for (String name: access_flags.getInnerClassModifiers())
                     print(name + " ");
-                if (info.inner_name_index!=0) {
+                if (info.inner_name_index != 0) {
                     print("#" + info.inner_name_index + "= ");
                 }
                 print("#" + info.inner_class_info_index);
                 if (info.outer_class_info_index != 0) {
                     print(" of #" + info.outer_class_info_index);
                 }
-                print("; //");
+                print(";");
+                tab();
+                print("// ");
                 if (info.inner_name_index != 0) {
                     print(getInnerName(constant_pool, info) + "=");
                 }
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/ConstantWriter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/ConstantWriter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -369,9 +369,21 @@
                     case '\r':
                         sb.append('\\').append('r');
                         break;
+                    case '\b':
+                        sb.append('\\').append('b');
+                        break;
+                    case '\f':
+                        sb.append('\\').append('f');
+                        break;
                     case '\"':
                         sb.append('\\').append('\"');
                         break;
+                    case '\'':
+                        sb.append('\\').append('\'');
+                        break;
+                    case '\\':
+                        sb.append('\\').append('\\');
+                        break;
                     default:
                         sb.append(c);
                 }
--- a/langtools/test/com/sun/javadoc/testOrdering/TestOrdering.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/com/sun/javadoc/testOrdering/TestOrdering.java	Wed Jul 05 20:00:07 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8039410 8042601 8042829 8049393
+ * @bug 8039410 8042601 8042829 8049393 8050031
  * @summary test to determine if members are ordered correctly
  * @author ksrini
  * @library ../lib/
--- a/langtools/test/tools/all/RunCodingRules.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/all/RunCodingRules.java	Wed Jul 05 20:00:07 2017 +0200
@@ -30,8 +30,12 @@
 
 import java.io.*;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
@@ -48,25 +52,26 @@
     }
 
     public void run() throws Exception {
-        File testSrc = new File(System.getProperty("test.src", "."));
-        File targetDir = new File(System.getProperty("test.classes", "."));
-        File sourceDir = null;
-        File crulesDir = null;
-        for (File d = testSrc; d != null; d = d.getParentFile()) {
-            if (new File(d, "TEST.ROOT").exists()) {
-                d = d.getParentFile();
-                File f = new File(d, "src/share/classes");
-                if (f.exists()) {
-                    sourceDir = f;
-                    f = new File(d, "make/tools");
-                    if (f.exists())
-                        crulesDir = f;
+        Path testSrc = Paths.get(System.getProperty("test.src", "."));
+        Path targetDir = Paths.get(System.getProperty("test.classes", "."));
+        List<Path> sourceDirs = null;
+        Path crulesDir = null;
+        for (Path d = testSrc; d != null; d = d.getParent()) {
+            if (Files.exists(d.resolve("TEST.ROOT"))) {
+                d = d.getParent();
+                Path toolsPath = d.resolve("make/tools");
+                if (Files.exists(toolsPath)) {
+                    crulesDir = toolsPath;
+                    sourceDirs = Files.walk(d.resolve("src"), 1)
+                                      .map(p -> p.resolve("share/classes"))
+                                      .filter(p -> Files.isDirectory(p))
+                                      .collect(Collectors.toList());
                     break;
                 }
             }
         }
 
-        if (sourceDir == null || crulesDir == null) {
+        if (sourceDirs == null || crulesDir == null) {
             System.err.println("Warning: sources not found, test skipped.");
             return ;
         }
@@ -77,35 +82,43 @@
             Assert.check(diagnostic.getKind() != Diagnostic.Kind.ERROR, diagnostic.toString());
         };
 
-        List<File> crulesFiles = Files.walk(crulesDir.toPath())
+        List<File> crulesFiles = Files.walk(crulesDir)
+                                      .filter(entry -> entry.getFileName().toString().endsWith(".java"))
+                                      .filter(entry -> entry.getParent().endsWith("crules"))
                                       .map(entry -> entry.toFile())
-                                      .filter(entry -> entry.getName().endsWith(".java"))
-                                      .filter(entry -> entry.getParentFile().getName().equals("crules"))
                                       .collect(Collectors.toList());
 
-        File crulesTarget = new File(targetDir, "crules");
-        crulesTarget.mkdirs();
-        List<String> crulesOptions = Arrays.asList("-d", crulesTarget.getAbsolutePath());
+        Path crulesTarget = targetDir.resolve("crules");
+        Files.createDirectories(crulesTarget);
+        List<String> crulesOptions = Arrays.asList("-d", crulesTarget.toString());
         javaCompiler.getTask(null, fm, noErrors, crulesOptions, null,
                 fm.getJavaFileObjectsFromFiles(crulesFiles)).call();
-        File registration = new File(crulesTarget, "META-INF/services/com.sun.source.util.Plugin");
-        registration.getParentFile().mkdirs();
-        try (Writer metaInfServices = new FileWriter(registration)) {
+        Path registration = crulesTarget.resolve("META-INF/services/com.sun.source.util.Plugin");
+        Files.createDirectories(registration.getParent());
+        try (Writer metaInfServices = Files.newBufferedWriter(registration, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
             metaInfServices.write("crules.CodingRulesAnalyzerPlugin\n");
         }
 
-        List<File> sources = Files.walk(sourceDir.toPath())
-                                  .map(entry -> entry.toFile())
-                                  .filter(entry -> entry.getName().endsWith(".java"))
-                                  .collect(Collectors.toList());
+        List<File> sources = sourceDirs.stream()
+                                       .flatMap(dir -> silentFilesWalk(dir))
+                                       .filter(entry -> entry.getFileName().toString().endsWith(".java"))
+                                       .map(p -> p.toFile())
+                                       .collect(Collectors.toList());
 
-        File sourceTarget = new File(targetDir, "classes");
-        sourceTarget.mkdirs();
-        String processorPath = crulesTarget.getAbsolutePath() + File.pathSeparator +
-                crulesDir.getAbsolutePath();
-        List<String> options = Arrays.asList("-d", sourceTarget.getAbsolutePath(),
+        Path sourceTarget = targetDir.resolve("classes");
+        Files.createDirectories(sourceTarget);
+        String processorPath = crulesTarget.toString() + File.pathSeparator + crulesDir.toString();
+        List<String> options = Arrays.asList("-d", sourceTarget.toString(),
                 "-processorpath", processorPath, "-Xplugin:coding_rules");
         javaCompiler.getTask(null, fm, noErrors, options, null,
                 fm.getJavaFileObjectsFromFiles(sources)).call();
     }
+
+    Stream<Path> silentFilesWalk(Path dir) throws IllegalStateException {
+        try {
+            return Files.walk(dir);
+        } catch (IOException ex) {
+            throw new IllegalStateException(ex);
+        }
+    }
 }
--- a/langtools/test/tools/javac/defaultMethods/Assertions.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/javac/defaultMethods/Assertions.java	Wed Jul 05 20:00:07 2017 +0200
@@ -26,20 +26,6 @@
 import java.util.HashSet;
 import java.util.Set;
 
-/*
- * @test
- * @bug 8025141
- * @ignore 8047675 test fails if run with assertions enabled in jtreg
- * @summary Interfaces must not contain non-public fields, ensure $assertionsDisabled
- *          is not generated into an interface
- * @compile Assertions.java
- * @run main/othervm -da test.Assertions
- * @run main/othervm -ea:test.Assertions test.Assertions Inner
- * @run main/othervm -ea:test.Outer test.Assertions Outer
- * @run main/othervm -ea:test.Another test.Assertions Another.Inner
- * @run main/othervm -ea:test... test.Assertions Inner Outer Another.Inner
- */
-
 public class Assertions {
     interface Inner {
         default void testInner() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/AssertionsTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 2014, 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 8025141
+ * @summary Interfaces must not contain non-public fields, ensure $assertionsDisabled
+ *          is not generated into an interface
+ * @library /tools/lib
+ * @build ToolBox Assertions AssertionsTest
+ * @run main AssertionsTest -da
+ * @run main AssertionsTest -ea:test.Assertions Inner
+ * @run main AssertionsTest -ea:test.Outer Outer
+ * @run main AssertionsTest -ea:test.Another Another.Inner
+ * @run main AssertionsTest -ea:test... Inner Outer Another.Inner
+ */
+
+import java.util.Arrays;
+
+public class AssertionsTest {
+
+    public static void main(String... args) throws Exception {
+        String testClasses = System.getProperty("test.classes");
+        ToolBox tb = new ToolBox();
+        tb.new JavaTask().classpath(testClasses)
+                         .vmOptions(args[0])
+                         .className("test.Assertions")
+                         .classArgs(Arrays.copyOfRange(args, 1, args.length))
+                         .includeStandardOptions(false)
+                         .run(ToolBox.Expect.SUCCESS)
+                         .writeAll();
+    }
+
+}
--- a/langtools/test/tools/javac/diags/MessageInfo.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/javac/diags/MessageInfo.java	Wed Jul 05 20:00:07 2017 +0200
@@ -168,7 +168,7 @@
             for (File d = testSrc; d != null; d = d.getParentFile()) {
                 if (new File(d, "TEST.ROOT").exists()) {
                     d = d.getParentFile();
-                    File f = new File(d, "src/share/classes/com/sun/tools/javac/resources/compiler.properties");
+                    File f = new File(d, "src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties");
                     if (f.exists()) {
                         msgFile = f;
                         break;
--- a/langtools/test/tools/javap/T4501661.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/javap/T4501661.java	Wed Jul 05 20:00:07 2017 +0200
@@ -38,10 +38,12 @@
         File javaFile = writeTestFile();
         File classFile = compileTestFile(javaFile);
         boolean[] values = { false, true };
-        for (boolean priv: values) {
-            for (boolean prot: values) {
-                for (boolean publ: values) {
-                    test(priv, prot, publ, classFile);
+        for (boolean pack : values) {
+            for (boolean priv : values) {
+                for (boolean prot : values) {
+                    for (boolean publ : values) {
+                        test(pack, priv, prot, publ, classFile);
+                    }
                 }
             }
         }
@@ -50,8 +52,10 @@
             throw new Exception(errors + " errors found");
     }
 
-    void test(boolean priv, boolean prot, boolean publ, File classFile) {
+    void test(boolean pack, boolean priv, boolean prot, boolean publ, File classFile) {
         List<String> args = new ArrayList<String>();
+        if (pack)
+            args.add("-package");
         if (priv)
             args.add("-private");
         if (prot)
--- a/langtools/test/tools/javap/T4975569.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/javap/T4975569.java	Wed Jul 05 20:00:07 2017 +0200
@@ -23,73 +23,85 @@
 
 /*
  * @test
- * @bug 4975569 6622215
+ * @bug 4975569 6622215 8034861
  * @summary javap doesn't print new flag bits
  */
 
 import java.io.*;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
-public class T4975569
-{
+public class T4975569 {
+    private static final String NEW_LINE = System.getProperty("line.separator");
+    private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
+
     public static void main(String... args) {
         new T4975569().run();
     }
 
     void run() {
-        verify("T4975569$Anno", "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION");
-        verify("T4975569$E",    "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM");
-        verify("T4975569$S",    "flags: ACC_BRIDGE, ACC_SYNTHETIC",
-                                "InnerClasses:\n     static");
-        verify("T4975569$V",    "void m(java.lang.String...)",
-                                "flags: ACC_VARARGS");
-        verify("T4975569$Prot", "InnerClasses:\n     protected");
-        //verify("T4975569$Priv", "InnerClasses");
+        verify(Anno.class.getName(), "flags: ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION");
+        verify(E.class.getName(),    "flags: ACC_FINAL, ACC_SUPER, ACC_ENUM");
+        verify(S.class.getName(),    "flags: ACC_BRIDGE, ACC_SYNTHETIC",
+                                     "InnerClasses:\n  static [# =\\w]+; +// ");
+        verify(V.class.getName(),    "void m\\(java.lang.String...\\)",
+                                     "flags: ACC_VARARGS");
+        verify(Prot.class.getName(), "InnerClasses:\n  protected [# =\\w]+; +// ");
+        verify(Priv.class.getName(), new String[]{"-p"},
+                                     "InnerClasses:\n  private [# =\\w]+; +// ");
+
         if (errors > 0)
             throw new Error(errors + " found.");
     }
 
-    void verify(String className, String... expects) {
-        String output = javap(className);
+    void verify(String className, String[] flags, String... expects) {
+        String output = javap(className, Arrays.asList(flags));
         for (String expect: expects) {
-            if (output.indexOf(expect)< 0)
+            Pattern expectPattern = Pattern.compile(expect);
+            Matcher matcher = expectPattern.matcher(output);
+            if (!matcher.find()) {
                 error(expect + " not found");
+            }
         }
     }
 
-    void error(String msg) {
-        System.err.println(msg);
-        errors++;
+    void verify(String className, String... expects) {
+        verify(className, new String[0], expects);
     }
 
     int errors;
+    void error(String msg) {
+        System.err.println(msg.replace("\n", NEW_LINE));
+        errors++;
+    }
 
-    String javap(String className) {
-        String newline = System.getProperty("line.separator");
-        String testClasses = System.getProperty("test.classes", ".");
+    String javap(String className, List<String> flags) {
         StringWriter sw = new StringWriter();
         PrintWriter out = new PrintWriter(sw);
-        String[] args = { "-v", "-classpath", testClasses, className };
-        int rc = com.sun.tools.javap.Main.run(args, out);
+        List<String> args = new ArrayList<>(flags);
+        args.addAll(Arrays.asList("-v", "-classpath", TEST_CLASSES, className));
+        int rc = com.sun.tools.javap.Main.run(args.toArray(new String[args.size()]), out);
+        out.close();
+        String output = sw.toString();
+        System.err.println("class " + className);
+        System.err.println(output);
+
         if (rc != 0)
             throw new Error("javap failed. rc=" + rc);
-        out.close();
-        String output = sw.toString().replaceAll(newline, "\n");
-        System.out.println("class " + className);
-        System.out.println(output);
-        return output;
+        return output.replaceAll(NEW_LINE, "\n");
     }
 
-    List x() { return null; };
+    List x() { return null; }
 
     class V { void m(String... args) { } }
-    enum E { e; }
+    enum E { e }
     @interface Anno { }
     static class S extends T4975569 {
         ArrayList x() { return null; }
     }
 
     protected class Prot { }
-    //private class Priv { int i; }
+    private class Priv { int i; }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javap/T8038414.java	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/*
+ * @test
+ * @bug 8038414
+ * @summary Constant pool's strings are not escaped properly
+ */
+public class T8038414 {
+    private static final String NEW_LINE = System.getProperty("line.separator");
+    private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
+    private static final String GOLDEN_STRING = escapeString(Test.test);
+
+    private static String escapeString(String s) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '\t':
+                    sb.append('\\').append('t');
+                    break;
+                case '\n':
+                    sb.append('\\').append('n');
+                    break;
+                case '\r':
+                    sb.append('\\').append('r');
+                    break;
+                case '\b':
+                    sb.append('\\').append('b');
+                    break;
+                case '\f':
+                    sb.append('\\').append('f');
+                    break;
+                case '\"':
+                    sb.append('\\').append('\"');
+                    break;
+                case '\'':
+                    sb.append('\\').append('\'');
+                    break;
+                case '\\':
+                    sb.append('\\').append('\\');
+                    break;
+                default:
+                    sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    public static void main(String... args) {
+        new T8038414().run();
+    }
+
+    public void run() {
+        String output = javap(Test.class.getName());
+        List<String> actualValues = extractEscapedComments(output);
+        for (String a : actualValues) {
+            check(!GOLDEN_STRING.equals(a), String.format("Expected: %s, got: %s", GOLDEN_STRING, a));
+        }
+    }
+
+    private List<String> extractConstantPool(String output) {
+        List<String> cp = new ArrayList<>();
+        boolean inCp = false;
+        for (String s : output.split("\n")) {
+            if (s.equals("{")) {
+                break;
+            }
+            if (inCp) {
+                cp.add(s);
+            }
+            if (s.equals("Constant pool:")) {
+                inCp = true;
+            }
+        }
+        return cp;
+    }
+
+    /**
+     * Returns a list which contains comments of the string entry in the constant pool
+     * and the appropriate UTF-8 value.
+     *
+     * @return a list
+     */
+    private List<String> extractEscapedComments(String output) {
+        List<String> result = new ArrayList<>();
+        Pattern stringPattern = Pattern.compile(" +#\\d+ = String +#(\\d+) +// +(.*)");
+        int index = -1;
+        List<String> cp = extractConstantPool(output);
+        for (String c : cp) {
+            Matcher matcher = stringPattern.matcher(c);
+            if (matcher.matches()) {
+                index = Integer.parseInt(matcher.group(1)) - 1;
+                result.add(matcher.group(2));
+                // only one String entry
+                break;
+            }
+        }
+        check(index == -1, "Escaped string is not found in constant pool");
+        result.add(cp.get(index).replaceAll(".* +", "")); // remove #16 = Utf8
+        return result;
+    }
+
+    private String javap(String className) {
+        StringWriter sw = new StringWriter();
+        PrintWriter out = new PrintWriter(sw);
+        int rc = com.sun.tools.javap.Main.run(new String[]{"-v", "-classpath", TEST_CLASSES, className}, out);
+        out.close();
+        String output = sw.toString();
+        System.err.println("class " + className);
+        System.err.println(output);
+
+        check(rc != 0, "javap failed. rc=" + rc);
+        return output.replaceAll(NEW_LINE, "\n");
+    }
+
+    private void check(boolean cond, String msg) {
+        if (cond) {
+            throw new RuntimeException(msg);
+        }
+    }
+
+    static class Test {
+        static String test = "\\t\t\b\r\n\f\"\'\\";
+    }
+}
--- a/langtools/test/tools/lib/ToolBox.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/langtools/test/tools/lib/ToolBox.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1568,6 +1568,20 @@
         }
 
         /**
+         * Sets whether or not the standard VM and java options for the test should be passed
+         * to the new VM instance. If this method is not called, the default behavior is that
+         * the options will be passed to the new VM instance.
+         *
+         * @param includeStandardOptions whether or not the standard VM and java options for
+         *                               the test should be passed to the new VM instance.
+         * @return this task object
+         */
+        public JavaTask includeStandardOptions(boolean includeStandardOptions) {
+            this.includeStandardOptions = includeStandardOptions;
+            return this;
+        }
+
+        /**
          * {@inheritDoc}
          * @return the name "java"
          */
--- a/make/CompileJavaModules.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/make/CompileJavaModules.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -89,7 +89,7 @@
 
 ################################################################################
 
-java.desktop_COPY := .gif .png .wav .txt .xml .css flavormap.properties
+java.desktop_COPY := .gif .png .wav .txt .xml .css flavormap.properties .pf
 java.desktop_CLEAN := iio-plugin.properties
 
 java.desktop_EXCLUDES += \
--- a/make/Main.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/make/Main.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -236,11 +236,11 @@
 
 # Creates the jar files (rt.jar resources.jar etc)
 main-jars:
-	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f CreateJars.gmk)
+	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) PROFILE="" -f CreateJars.gmk)
 
 # Creates the images (j2sdk-image j2re-image etc)
 images:
-	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Images.gmk)
+	+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) PROFILE="" -f Images.gmk)
         ifeq ($(OPENJDK_TARGET_OS), macosx)
 	  +($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f Bundles.gmk)
         endif
--- a/make/common/MakeBase.gmk	Wed Jul 05 19:59:05 2017 +0200
+++ b/make/common/MakeBase.gmk	Wed Jul 05 20:00:07 2017 +0200
@@ -349,7 +349,7 @@
     # (and causing a crash on Cygwin).
     # Default shell seems to always be /bin/sh. Must override with bash to get this to work on Solaris.
     # Only use time if it's GNU time which supports format and output file.
-    WRAPPER_SHELL:=/bin/bash $$(SRC_ROOT)/common/bin/shell-tracer.sh $$(if $$(findstring yes,$$(IS_GNU_TIME)),$$(TIME),-) $$(OUTPUT_ROOT)/build-trace-time.log /bin/bash
+    WRAPPER_SHELL:=$$(BASH) $$(SRC_ROOT)/common/bin/shell-tracer.sh $$(if $$(findstring yes,$$(IS_GNU_TIME)),$$(TIME),-) $$(OUTPUT_ROOT)/build-trace-time.log /bin/bash
     SHELL=$$(warning $$(if $$@,Building $$@,Running shell command) $$(if $$<, (from $$<))$$(if $$?, ($$(wordlist 1, 20, $$?) $$(if $$(wordlist 21, 22, $$?), ... [in total $$(words $$?) files]) newer)))$$(WRAPPER_SHELL)
   endif
   # Never remove warning messages; this is just for completeness
--- a/nashorn/.hgtags	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/.hgtags	Wed Jul 05 20:00:07 2017 +0200
@@ -262,3 +262,4 @@
 ed60a4e9dd35dcabb9b24e90434f5f615d988981 jdk9-b26
 221a84ef44c00335b563d92f470efaf8162b471e jdk9-b27
 00c31e5eaf26f9b238165157b9d1c617b03abcb6 jdk9-b28
+e541ebaf2ab7038333ad0c13f4decd327c26dd15 jdk9-b29
--- a/nashorn/bin/dump_octane_code.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-
-#
-# The purpose of this script is to provide a large amount of IR/bytecode from a known
-# application to be diffed against the same output with a different Nashorn version.
-# That way we can quickly detect if a seemingly minute change modifies a lot of code,
-# which it most likely shouldn't. One example of this was when AccessSpecializer was
-# moved into Lower the first time, it worked fine, but as a lot of Scope information
-# at the time was finalized further down the code pipeline it did a lot fewer callsite
-# specializations. This would have been immediately detected with a before and after 
-# diff using the output from this script.
-#
-
-ITERS=$1
-if [ -z $ITERS ]; then 
-    ITERS=7
-fi
-NASHORN_JAR=dist/nashorn.jar
-JVM_FLAGS="-ea -esa -server -jar ${NASHORN_JAR}"
-
-BENCHMARKS=( "box2d.js" "code-load.js" "crypto.js" "deltablue.js" "earley-boyer.js" "gbemu.js" "mandreel.js" "navier-stokes.js" "pdfjs.js" "raytrace.js" "regexp.js" "richards.js" "splay.js" )
-
-for BENCHMARK in "${BENCHMARKS[@]}"
-do     
-    echo "START: ${BENCHMARK}"
-    CMD="${JAVA_HOME}/bin/java ${JVM_FLAGS} -co --print-lower-parse test/script/external/octane/${BENCHMARK}"
-    $CMD
-    echo "END: ${BENCHMARK}"
-    echo ""
-done
-
-echo "Done"
--- a/nashorn/bin/fixorphantests.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-
-#ensure that all tests tagged with @test are also tagged with @run
-
-for f in $(find test/script/basic/*.js); do 
-    grep @test $f >/dev/null
-    TEST=$?
-    grep @run $f >/dev/null
-    RUN=$?    
-
-    if [ $TEST -eq 0 ] && [ ! $RUN -eq 0 ]; then		
-	echo "repairing ${f}..."
-	TEMP=$(mktemp /tmp/scratch.XXXXXX)
-
-	#IFS='', -raw flag to preserve white space
-	while IFS='' read -r line; do 	    
-	    echo $line | grep @test >/dev/null
-	    TEST=$?
-	    printf "%s\n" "$line" 
-	    if [ $TEST -eq 0 ]; then
-		printf "%s\n" "$line" | sed s/@test/@run/g 
-	    fi	   
-	done < $f >$TEMP
-
-	cp $TEMP $f
-
-	rm -fr $TEMP
-    fi
-
-done
--- a/nashorn/bin/fixwhitespace.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-
-fix() {
-    #convert tabs to spaces
-    find . -name $1 -exec sed -i "" 's/	/    /g' {} \;
-    #remove trailing whitespace
-    find . -name $1 -exec sed -i "" 's/[ 	]*$//' \{} \;
-}
-
-if [ ! -z $1 ]; then 
-    fix $1;
-else
-    fix "*.java"
-    fix "*.js"
-fi
--- a/nashorn/bin/jjsdebug.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2014, 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.
-#
-
-$JAVA_HOME/bin/jjs -J-Djava.ext.dirs=`dirname $0`/../dist -J-agentlib:jdwp=transport=dt_socket,address=localhost:9009,server=y,suspend=y $*
--- a/nashorn/bin/rm-non-tracked.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-# 
-# 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.
-#
-hg status|grep ^\?|awk '{print $2}'|xargs rm
--- a/nashorn/bin/run_octane.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2010, 2014, 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.
-#
-
-LOG="./octane_$(date|sed "s/ /_/g"|sed "s/:/_/g").log"
-
-run_one() {
-    sh ../bin/runopt.sh -scripting ../test/script/basic/run-octane.js -- $1 --verbose --iterations 25 | tee -a $LOG
-}
-
-if [ -z $1 ]; then 
-
-    run_one "box2d"
-    run_one "code-load"
-    run_one "crypto"
-    run_one "deltablue"
-    run_one "earley-boyer"
-    run_one "gbemu"
-    run_one "mandreel"
-    run_one "navier-stokes"
-    run_one "pdfjs"
-    run_one "raytrace"
-    run_one "regexp"
-    run_one "richards"
-    run_one "splay"
-    run_one "typescript"
-    run_one "zlib"
-
-else
-    run_one $1
-fi
--- a/nashorn/bin/rundiff.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-# do two runs of a script, one optimistic and one pessimistic, expect identical outputs
-# if not, display and error message and a diff
-
-which opendiff >/dev/null
-RES=$?
-if [ $RES = 0 ]; then
-    DIFFTOOL=opendiff
-else
-    DIFFTOOL=diff
-fi
-
-OPTIMISTIC=out_optimistic
-PESSIMISTIC=out_pessimistic
-$JAVA_HOME/bin/java -ea -jar ../dist/nashorn.jar ${@} >$PESSIMISTIC
-$JAVA_HOME/bin/java -ea -Dnashorn.optimistic -jar ../dist/nashorn.jar ${@} >$OPTIMISTIC
-
-if ! diff -q $PESSIMISTIC $OPTIMISTIC >/dev/null ; then
-    echo "Failure! Results are different"
-    echo ""
-    $DIFFTOOL $PESSIMISTIC $OPTIMISTIC
-else
-    echo "OK - Results are identical"
-fi
--- a/nashorn/bin/runopt.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010, 2014, 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.
-#
-
-###########################################################################################
-# This is a helper script to evaluate nashorn with optimistic types
-# it produces a flight recording for every run, and uses the best 
-# known flags for performance for the current configration
-###########################################################################################
-
-# Flags to instrument lambdaform computation, caching, interpretation and compilation
-# Default compile threshold for lambdaforms is 30
-#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
-
-
-# Flags to run trusted tests from the Nashorn test suite
-#FLAGS="-Djava.security.manager -Djava.security.policy=../build/nashorn.policy -Dnashorn.debug"
-
-
-# Unique timestamped file name for JFR recordings. For JFR, we also have to
-# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form
-# stack traces.
-#
-# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and
-# set the "method-sampling-interval" Normal and Maximum sample time as low as you
-# can go (10 ms on most platforms). The default is normally higher. The increased
-# sampling overhead is usually negligible for Nashorn runs, but the data is better
-
-JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
-
-
-# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming
-# that we run the script from the make dir
-DIR=..
-NASHORN_JAR=$DIR/dist/nashorn.jar
-
-
-# The built Nashorn jar is placed first in the bootclasspath to override the JDK
-# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in
-# nashorn count as system assertions in this configuration
-
-# Type profiling default level is 111, 222 adds some compile time, but is faster
-
-$JAVA_HOME/bin/java \
-$FLAGS \
--ea \
--esa \
--Xbootclasspath/p:$NASHORN_JAR \
--Xms2G -Xmx2G \
--XX:TypeProfileLevel=222 \
--cp $CLASSPATH:../build/test/classes/ \
-jdk.nashorn.tools.Shell ${@}
-
-# Below are flags that may come in handy, but aren't used for default runs
-
-# Testing out new code optimizations using the generic hotspot "new code" parameter
-#-XX:+UnlockDiagnosticVMOptions \
-#-XX:+UseNewCode \
-
-# Flight recorder
-#-XX:+UnlockCommercialFeatures \
-#-XX:+FlightRecorder \
-#-XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024 \
-
-
-# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine,
-# keeping this flag around for experimental reasons. Replace + with - to switch it off
-#-XX:+UseTypeSpeculation \
-
-
-# Same with math intrinsics. They should be enabled by default in 8u20 and 9
-#-XX:+UseMathExactIntrinsics \
-
-
-# Add -Dnashorn.time to time the compilation phases.
-#-Dnashorn.time \
-
-
-# Add ShowHiddenFrames to get lambda form internals on the stack traces
-#-XX:+ShowHiddenFrames \
-
-
-# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product,
-# That tired compilation is switched off, for C2 only output and that the number of
-# compiler threads is set to 1 for determinsm.
-#-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \
-
-# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments)
-# -XX:IncreaseFirstTierCompileThresholdAt=XX
-
--- a/nashorn/bin/runopt_noassert.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
-
-FILENAME="./optimistic_noassert_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
-
-DIR=..
-NASHORN_JAR=$DIR/dist/nashorn.jar
-
-$JAVA_HOME/bin/java \
-$FLAGS \
--Xbootclasspath/p:$NASHORN_JAR \
--Xms2G -Xmx2G \
--XX:+UnlockCommercialFeatures \
--XX:+FlightRecorder \
--XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$FILENAME,stackdepth=1024 \
--XX:TypeProfileLevel=222 \
--XX:+UnlockExperimentalVMOptions \
--XX:+UseTypeSpeculation \
--XX:+UseMathExactIntrinsics \
--XX:+UnlockDiagnosticVMOptions \
--cp $CLASSPATH:../build/test/classes/ \
-jdk.nashorn.tools.Shell ${@}
-
-#-XX:+ShowHiddenFrames \
-#-XX:+PrintOptoAssembly \
-#-XX:-TieredCompilation \
-#-XX:CICompilerCount=1 \
--- a/nashorn/bin/runopt_nojfr.sh	Wed Jul 05 19:59:05 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-#FLAGS="-Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
-
-DIR=..
-NASHORN_JAR=$DIR/dist/nashorn.jar
-
-$JAVA_HOME/bin/java \
-$FLAGS \
--ea \
--esa \
--Xbootclasspath/p:$NASHORN_JAR \
--Xms2G -Xmx2G \
--XX:+UnlockCommercialFeatures \
--XX:TypeProfileLevel=222 \
--XX:+UnlockExperimentalVMOptions \
--XX:+UseTypeSpeculation \
--XX:+UseMathExactIntrinsics \
--XX:+UnlockDiagnosticVMOptions \
--XX:+UseNewCode \
--cp $CLASSPATH:../build/test/classes/ \
-jdk.nashorn.tools.Shell ${@}
-
-#-XX:+ShowHiddenFrames \
-#-XX:+PrintOptoAssembly \
-#-XX:-TieredCompilation \
-#-XX:CICompilerCount=1 \
--- a/nashorn/make/build.xml	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/make/build.xml	Wed Jul 05 20:00:07 2017 +0200
@@ -341,6 +341,13 @@
     permission java.util.PropertyPermission "nashorn.test.*", "read";
 };
 
+grant codeBase "file:/${basedir}/test/script/basic/es6/*" {
+    permission java.io.FilePermission "${basedir}/test/script/-", "read";
+    permission java.io.FilePermission "$${user.dir}", "read";
+    permission java.util.PropertyPermission "user.dir", "read";
+    permission java.util.PropertyPermission "nashorn.test.*", "read";
+};
+
 grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" {
     permission java.util.PropertyPermission "java.security.policy", "read";
 };
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/AssignSymbols.java	Wed Jul 05 20:00:07 2017 +0200
@@ -36,6 +36,7 @@
 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
 import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE;
+import static jdk.nashorn.internal.ir.Symbol.IS_CONST;
 import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
 import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
 import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
@@ -83,11 +84,13 @@
 import jdk.nashorn.internal.ir.UnaryNode;
 import jdk.nashorn.internal.ir.VarNode;
 import jdk.nashorn.internal.ir.WithNode;
-import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
 import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.Property;
-import jdk.nashorn.internal.runtime.PropertyMap;
+import jdk.nashorn.internal.runtime.ECMAErrors;
+import jdk.nashorn.internal.runtime.ErrorManager;
+import jdk.nashorn.internal.runtime.JSErrorType;
+import jdk.nashorn.internal.runtime.ParserException;
+import jdk.nashorn.internal.runtime.Source;
 import jdk.nashorn.internal.runtime.logging.DebugLogger;
 import jdk.nashorn.internal.runtime.logging.Loggable;
 import jdk.nashorn.internal.runtime.logging.Logger;
@@ -101,7 +104,7 @@
  * visitor.
  */
 @Logger(name="symbols")
-final class AssignSymbols extends NodeOperatorVisitor<LexicalContext> implements Loggable {
+final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggable {
     private final DebugLogger log;
     private final boolean     debug;
 
@@ -190,8 +193,7 @@
      * @param body the body of the FunctionNode we are entering
      */
     private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
-        // This visitor will assign symbol to all declared variables, except function declarations (which are taken care
-        // in a separate step above) and "var" declarations in for loop initializers.
+        // This visitor will assign symbol to all declared variables, except "var" declarations in for loop initializers.
         //
         body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
             @Override
@@ -204,8 +206,8 @@
             public Node leaveVarNode(final VarNode varNode) {
                 if (varNode.isStatement()) {
                     final IdentNode ident  = varNode.getName();
-                    final Symbol    symbol = defineSymbol(body, ident.getName(), IS_VAR);
-                    functionNode.addDeclaredSymbol(symbol);
+                    final Block block = varNode.isBlockScoped() ? getLexicalContext().getCurrentBlock() : body;
+                    final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags());
                     if (varNode.isFunctionDeclaration()) {
                         symbol.setIsFunctionDeclaration();
                     }
@@ -303,23 +305,31 @@
         return functionNode.setBody(lc, body.setStatements(lc, newStatements));
     }
 
-    private Symbol defineGlobalSymbol(final Block block, final String name) {
-        return defineSymbol(block, name, IS_GLOBAL);
-    }
-
     /**
      * Defines a new symbol in the given block.
      *
      * @param block        the block in which to define the symbol
      * @param name         name of symbol.
+     * @param origin       origin node
      * @param symbolFlags  Symbol flags.
      *
      * @return Symbol for given name or null for redefinition.
      */
-    private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
+    private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
         int    flags  = symbolFlags;
-        Symbol symbol = findSymbol(block, name); // Locate symbol.
-        final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
+        final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
+        final boolean isGlobal     = (flags & KINDMASK) == IS_GLOBAL;
+
+        Symbol symbol;
+        final FunctionNode function;
+        if (isBlockScope) {
+            // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
+            symbol = block.getExistingSymbol(name);
+            function = lc.getCurrentFunction();
+        } else {
+            symbol = findSymbol(block, name);
+            function = lc.getFunction(block);
+        }
 
         // Global variables are implicitly always scope variables too.
         if (isGlobal) {
@@ -333,7 +343,6 @@
         final boolean isParam = (flags & KINDMASK) == IS_PARAM;
         final boolean isVar =   (flags & KINDMASK) == IS_VAR;
 
-        final FunctionNode function = lc.getFunction(block);
         if (symbol != null) {
             // Symbol was already defined. Check if it needs to be redefined.
             if (isParam) {
@@ -345,10 +354,21 @@
                     throw new AssertionError("duplicate parameter");
                 }
             } else if (isVar) {
-                if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
+                if (isBlockScope) {
+                    // Check redeclaration in same block
+                    if (symbol.hasBeenDeclared()) {
+                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
+                    } else {
+                        symbol.setHasBeenDeclared();
+                    }
+                } else if ((flags & IS_INTERNAL) != 0) {
                     // Always create a new definition.
                     symbol = null;
                 } else {
+                    // Found LET or CONST in parent scope of same function - s SyntaxError
+                    if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) {
+                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
+                    }
                     // Not defined in this function. Create a new definition.
                     if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
                         symbol = null;
@@ -359,10 +379,10 @@
 
         if (symbol == null) {
             // If not found, then create a new one.
-            Block symbolBlock;
+            final Block symbolBlock;
 
             // Determine where to create it.
-            if (isVar && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
+            if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
                 symbolBlock = block; //internal vars are always defined in the block closest to them
             } else if (isGlobal) {
                 symbolBlock = lc.getOutermostFunction().getBody();
@@ -420,9 +440,9 @@
     @Override
     public boolean enterBlock(final Block block) {
         start(block);
-        block.clearSymbols();
 
         if (lc.isFunctionBody()) {
+            block.clearSymbols();
             enterFunctionBody();
         }
 
@@ -441,7 +461,10 @@
         // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its
         // symbol is naturally internal, and should be treated as such.
         final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName());
-        defineSymbol(block, exname, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
+        // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to
+        // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block.
+        final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
+        symbol.clearFlag(IS_LET);
 
         return true;
     }
@@ -452,15 +475,13 @@
 
         initFunctionWideVariables(functionNode, body);
 
-        if (functionNode.isProgram()) {
-            initGlobalSymbols(body);
-        } else if (!functionNode.isDeclared() && !functionNode.isAnonymous()) {
+        if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) {
             // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's
             // anonymous.
             final String name = functionNode.getIdent().getName();
             assert name != null;
             assert body.getExistingSymbol(name) == null;
-            defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
+            defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
             if(functionNode.allVarsInScope()) { // basically, has deep eval
                 lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
             }
@@ -485,7 +506,8 @@
         if (functionNode.isDeclared()) {
             final Iterator<Block> blocks = lc.getBlocks();
             if (blocks.hasNext()) {
-                defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
+                final IdentNode ident = functionNode.getIdent();
+                defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
             }
         }
 
@@ -495,10 +517,16 @@
     @Override
     public boolean enterVarNode(final VarNode varNode) {
         start(varNode);
-        defineSymbol(lc.getCurrentBlock(), varNode.getName().getName(), IS_VAR | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
         return true;
     }
 
+    @Override
+    public Node leaveVarNode(final VarNode varNode) {
+        final IdentNode ident = varNode.getName();
+        defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
+        return super.leaveVarNode(varNode);
+    }
+
     private Symbol exceptionSymbol() {
         return newObjectInternal(EXCEPTION_PREFIX);
     }
@@ -597,7 +625,7 @@
     }
 
     private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
-        defineSymbol(block, cc.symbolName(), flags).setNeedsSlot(true);
+        defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true);
     }
 
     private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
@@ -608,7 +636,7 @@
             initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
             if (functionNode.needsArguments()) {
                 initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
-                defineSymbol(body, ARGUMENTS_VAR.symbolName(), IS_VAR | HAS_OBJECT_VALUE);
+                defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE);
             }
         }
 
@@ -617,20 +645,6 @@
         initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL);
     }
 
-
-    /**
-     * Move any properties from the global map into the scope of this function (which must be a program function).
-     * @param block the function node body for which to init scope vars
-     */
-    private void initGlobalSymbols(final Block block) {
-        final PropertyMap map = Context.getGlobalMap();
-
-        for (final Property property : map.getProperties()) {
-            final Symbol symbol = defineGlobalSymbol(block, property.getKey());
-            log.info("Added global symbol from property map ", symbol);
-        }
-    }
-
     /**
      * Initialize parameters for function node.
      * @param functionNode the function node
@@ -639,7 +653,7 @@
         final boolean isVarArg = functionNode.isVarArg();
         final boolean scopeParams = functionNode.allVarsInScope() || isVarArg;
         for (final IdentNode param : functionNode.getParameters()) {
-            final Symbol symbol = defineSymbol(body, param.getName(), IS_PARAM);
+            final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM);
             if(scopeParams) {
                 // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored.
                 // It will force creation of scopes where they would otherwise not necessarily be needed (functions
@@ -665,10 +679,29 @@
         return definingFn == function;
     }
 
+    private void checkConstAssignment(final IdentNode ident) {
+        // Check for reassignment of constant
+        final Symbol symbol = ident.getSymbol();
+        if (symbol.isConst()) {
+            throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident);
+        }
+    }
+
     @Override
-    public Node leaveASSIGN(final BinaryNode binaryNode) {
+    public Node leaveBinaryNode(final BinaryNode binaryNode) {
+        if (binaryNode.isAssignment() && binaryNode.lhs() instanceof IdentNode) {
+            checkConstAssignment((IdentNode) binaryNode.lhs());
+        }
+        switch (binaryNode.tokenType()) {
+        case ASSIGN:
+            return leaveASSIGN(binaryNode);
+        default:
+            return super.leaveBinaryNode(binaryNode);
+        }
+    }
+
+    private Node leaveASSIGN(final BinaryNode binaryNode) {
         // If we're assigning a property of the this object ("this.foo = ..."), record it.
-
         final Expression lhs = binaryNode.lhs();
         if (lhs instanceof AccessNode) {
             final AccessNode accessNode = (AccessNode) lhs;
@@ -684,6 +717,21 @@
     }
 
     @Override
+    public Node leaveUnaryNode(final UnaryNode unaryNode) {
+        if (unaryNode.isAssignment() && unaryNode.getExpression() instanceof IdentNode) {
+            checkConstAssignment((IdentNode) unaryNode.getExpression());
+        }
+        switch (unaryNode.tokenType()) {
+        case DELETE:
+            return leaveDELETE(unaryNode);
+        case TYPEOF:
+            return leaveTYPEOF(unaryNode);
+        default:
+            return super.leaveUnaryNode(unaryNode);
+        }
+    }
+
+    @Override
     public Node leaveBlock(final Block block) {
         // It's not necessary to guard the marking of symbols as locals with this "if"condition for correctness, it's
         // just an optimization -- runtime type calculation is not used when the compilation is not an on-demand
@@ -699,8 +747,7 @@
         return block;
     }
 
-    @Override
-    public Node leaveDELETE(final UnaryNode unaryNode) {
+    private Node leaveDELETE(final UnaryNode unaryNode) {
         final FunctionNode currentFunctionNode = lc.getCurrentFunction();
         final boolean      strictMode          = currentFunctionNode.isStrict();
         final Expression   rhs                 = unaryNode.getExpression();
@@ -799,9 +846,8 @@
             // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
             maybeForceScope(symbol);
         } else {
-            log.info("No symbol exists. Declare as global: ", symbol);
-            symbol = defineGlobalSymbol(block, name);
-            Symbol.setSymbolIsScope(lc, symbol);
+            log.info("No symbol exists. Declare as global: ", name);
+            symbol = defineSymbol(block, name, identNode, IS_GLOBAL | IS_SCOPE);
         }
 
         functionUsesSymbol(symbol);
@@ -810,7 +856,15 @@
             symbol.increaseUseCount();
         }
 
-        return end(identNode.setSymbol(symbol));
+        IdentNode newIdentNode = identNode.setSymbol(symbol);
+
+        // If a block-scoped var is used before its declaration mark it as dead.
+        // We can only statically detect this for local vars, cross-function symbols require runtime checks.
+        if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
+            newIdentNode = newIdentNode.markDead();
+        }
+
+        return end(newIdentNode);
     }
 
     @Override
@@ -834,8 +888,7 @@
         return tryNode;
     }
 
-    @Override
-    public Node leaveTYPEOF(final UnaryNode unaryNode) {
+    private Node leaveTYPEOF(final UnaryNode unaryNode) {
         final Expression rhs = unaryNode.getExpression();
 
         final List<Expression> args = new ArrayList<>();
@@ -875,7 +928,7 @@
     }
 
     private Symbol newInternal(final CompilerConstants cc, final int flags) {
-        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), IS_VAR | IS_INTERNAL | flags); //NASHORN-73
+        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73
     }
 
     private Symbol newObjectInternal(final CompilerConstants cc) {
@@ -915,7 +968,8 @@
             return false;
         }
 
-        if (lc.getCurrentFunction().allVarsInScope()) {
+        final FunctionNode func = lc.getCurrentFunction();
+        if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) {
             return true;
         }
 
@@ -955,4 +1009,16 @@
         final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits();
         return !(units == null || units.isEmpty());
     }
+
+    private void throwParserException(final String message, final Node origin) {
+        if (origin == null) {
+            throw new ParserException(message);
+        }
+        final Source source = compiler.getSource();
+        final long token = origin.getToken();
+        final int line = source.getLine(origin.getStart());
+        final int column = source.getColumn(origin.getStart());
+        final String formatted = ErrorManager.format(message, source, line, column, token);
+        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token);
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -52,6 +52,7 @@
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL;
+import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_DECLARE;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
@@ -302,6 +303,7 @@
      * @return the method generator used
      */
     private MethodEmitter loadIdent(final IdentNode identNode, final TypeBounds resultBounds) {
+        checkTemporalDeadZone(identNode);
         final Symbol symbol = identNode.getSymbol();
 
         if (!symbol.isScope()) {
@@ -334,6 +336,15 @@
         return method;
     }
 
+    // Any access to LET and CONST variables before their declaration must throw ReferenceError.
+    // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a
+    private void checkTemporalDeadZone(final IdentNode identNode) {
+        if (identNode.isDead()) {
+            method.load(identNode.getSymbol().getName());
+            method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR);
+        }
+    }
+
     private boolean isRestOf() {
         return continuationEntryPoints != null;
     }
@@ -3216,27 +3227,34 @@
             return false;
         }
         final Expression init = varNode.getInit();
+        final IdentNode identNode = varNode.getName();
+        final Symbol identSymbol = identNode.getSymbol();
+        assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
+        final boolean needsScope = identSymbol.isScope();
 
         if (init == null) {
+            if (needsScope && varNode.isBlockScoped()) {
+                // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
+                method.loadCompilerConstant(SCOPE);
+                method.loadUndefined(Type.OBJECT);
+                final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
+                assert isFastScope(identSymbol);
+                storeFastScopeVar(identSymbol, flags);
+            }
             return false;
         }
 
         enterStatement(varNode);
-
-        final IdentNode identNode = varNode.getName();
-        final Symbol identSymbol = identNode.getSymbol();
-        assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
-
         assert method != null;
 
-        final boolean needsScope = identSymbol.isScope();
         if (needsScope) {
             method.loadCompilerConstant(SCOPE);
         }
 
         if (needsScope) {
             loadExpressionUnbounded(init);
-            final int flags = CALLSITE_SCOPE | getCallSiteFlags();
+            // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
+            final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
             if (isFastScope(identSymbol)) {
                 storeFastScopeVar(identSymbol, flags);
             } else {
@@ -4343,6 +4361,9 @@
         protected abstract void evaluate();
 
         void store() {
+            if (target instanceof IdentNode) {
+                checkTemporalDeadZone((IdentNode)target);
+            }
             prologue();
             evaluate(); // leaves an operation of whatever the operationType was on the stack
             storeNonDiscard();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Compiler.java	Wed Jul 05 20:00:07 2017 +0200
@@ -59,7 +59,9 @@
 import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
 import jdk.nashorn.internal.runtime.CodeInstaller;
 import jdk.nashorn.internal.runtime.Context;
+import jdk.nashorn.internal.runtime.ErrorManager;
 import jdk.nashorn.internal.runtime.FunctionInitializer;
+import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptObject;
@@ -89,6 +91,8 @@
 
     private final String sourceName;
 
+    private final ErrorManager errors;
+
     private final boolean optimistic;
 
     private final Map<String, byte[]> bytecode;
@@ -311,6 +315,7 @@
      * @param env       script environment
      * @param installer code installer
      * @param source    source to compile
+     * @param errors    error manager
      * @param isStrict  is this a strict compilation
      */
     public Compiler(
@@ -318,8 +323,9 @@
             final ScriptEnvironment env,
             final CodeInstaller<ScriptEnvironment> installer,
             final Source source,
+            final ErrorManager errors,
             final boolean isStrict) {
-        this(context, env, installer, source, isStrict, false, null, null, null, null, null, null);
+        this(context, env, installer, source, errors, isStrict, false, null, null, null, null, null, null);
     }
 
     /**
@@ -329,6 +335,7 @@
      * @param env                      script environment
      * @param installer                code installer
      * @param source                   source to compile
+     * @param errors                   error manager
      * @param isStrict                 is this a strict compilation
      * @param isOnDemand               is this an on demand compilation
      * @param compiledFunction         compiled function, if any
@@ -343,6 +350,7 @@
             final ScriptEnvironment env,
             final CodeInstaller<ScriptEnvironment> installer,
             final Source source,
+            final ErrorManager errors,
             final boolean isStrict,
             final boolean isOnDemand,
             final RecompilableScriptFunctionData compiledFunction,
@@ -359,6 +367,7 @@
         this.bytecode                 = new LinkedHashMap<>();
         this.log                      = initLogger(context);
         this.source                   = source;
+        this.errors                   = errors;
         this.sourceName               = FunctionNode.getSourceName(source);
         this.onDemand                 = isOnDemand;
         this.compiledFunction         = compiledFunction;
@@ -524,7 +533,17 @@
 
         for (final CompilationPhase phase : phases) {
             log.fine(phase, " starting for ", quote(name));
-            newFunctionNode = phase.apply(this, phases, newFunctionNode);
+
+            try {
+                newFunctionNode = phase.apply(this, phases, newFunctionNode);
+            } catch (final ParserException error) {
+                errors.error(error);
+                if (env._dump_on_error) {
+                    error.printStackTrace(env.getErr());
+                }
+                return null;
+            }
+
             log.fine(phase, " done for function ", quote(name));
 
             if (env._print_mem_usage) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/DumpBytecode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/DumpBytecode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -89,7 +89,7 @@
 
 
             // should code be dumped to disk - only valid in compile_only mode?
-            if (env._dest_dir != null && env._compile_only) {
+            if (env._dest_dir != null) {
                 final String fileName = className.replace('.', File.separatorChar) + ".class";
                 final int    index    = fileName.lastIndexOf(File.separatorChar);
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -69,9 +69,7 @@
      * Constructor
      *
      * @param codegen  code generator
-     * @param keys     keys for fields in object
-     * @param symbols  symbols for fields in object
-     * @param values   list of values corresponding to keys
+     * @param tuples   tuples for fields in object
      */
     FieldObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples) {
         this(codegen, tuples, false, false);
@@ -81,9 +79,7 @@
      * Constructor
      *
      * @param codegen      code generator
-     * @param keys         keys for fields in object
-     * @param symbols      symbols for fields in object
-     * @param values       values (or null where no value) to be written to the fields
+     * @param tuples       tuples for fields in object
      * @param isScope      is this a scope object
      * @param hasArguments does the created object have an "arguments" property
      */
@@ -165,7 +161,7 @@
      * @param method      Script method.
      * @param key         Property key.
      * @param fieldIndex  Field number.
-     * @param value       Value to store.
+     * @param tuple       Tuple to store.
      */
     private void putField(final MethodEmitter method, final String key, final int fieldIndex, final MapTuple<T> tuple) {
         method.dup();
@@ -188,7 +184,7 @@
      *
      * @param method Script method.
      * @param index  Slot index.
-     * @param value  Value to store.
+     * @param tuple  Tuple to store.
      */
     private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) {
         method.dup();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapCreator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MapCreator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -52,8 +52,7 @@
      * Constructor
      *
      * @param structure structure to generate map for (a JO subclass)
-     * @param keys      list of keys for map
-     * @param symbols   list of symbols for map
+     * @param tuples    list of tuples for map
      */
     MapCreator(final Class<? extends ScriptObject> structure, final List<MapTuple<T>> tuples) {
         this.structure = structure;
@@ -149,6 +148,15 @@
             flags |= Property.IS_FUNCTION_DECLARATION;
         }
 
+        if (symbol.isConst()) {
+            flags |= Property.NOT_WRITABLE;
+        }
+
+        // Mark symbol as needing declaration. Access before declaration will throw a ReferenceError.
+        if (symbol.isBlockScoped() && symbol.isScope()) {
+            flags |= Property.NEEDS_DECLARATION;
+        }
+
         return flags;
     }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java	Wed Jul 05 20:00:07 2017 +0200
@@ -2233,9 +2233,8 @@
     /**
      * Generate dynamic setter. Pop receiver and property from stack.
      *
-     * @param valueType the type of the value to set
-     * @param name      name of property
-     * @param flags     call site flags
+     * @param name  name of property
+     * @param flags call site flags
      */
      void dynamicSet(final String name, final int flags) {
          assert !isOptimistic(flags);
@@ -2462,7 +2461,6 @@
      * Register line number at a label
      *
      * @param line  line number
-     * @param label label
      */
     void lineNumber(final int line) {
         if (context.getEnv()._debug_lines) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Wed Jul 05 20:00:07 2017 +0200
@@ -31,9 +31,11 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.security.AccessController;
 import java.security.MessageDigest;
 import java.security.PrivilegedAction;
@@ -41,6 +43,14 @@
 import java.util.Base64;
 import java.util.Date;
 import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
 import jdk.nashorn.internal.codegen.types.Type;
 import jdk.nashorn.internal.runtime.Context;
 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
@@ -49,30 +59,66 @@
 import jdk.nashorn.internal.runtime.options.Options;
 
 /**
- * Static utility that encapsulates persistence of decompilation information for functions. Normally, the type info
- * persistence feature is enabled and operates in an operating-system specific per-user cache directory. You can
- * override the directory by specifying it in the {@code nashorn.typeInfo.cacheDir} directory. Also, you can disable the
- * type info persistence altogether by specifying the {@code nashorn.typeInfo.disabled} system property.
+ * Static utility that encapsulates persistence of type information for functions compiled with optimistic
+ * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized,
+ * the type information for deoptimization is stored in a cache file. If the same function is compiled in a
+ * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system
+ * to skip a lot of intermediate recompilations and immediately emit a version of the code that has its
+ * optimistic types at (or near) the steady state.
+ * </p><p>
+ * Normally, the type info persistence feature is disabled. When the {@code nashorn.typeInfo.maxFiles} system
+ * property is specified with a value greater than 0, it is enabled and operates in an operating-system
+ * specific per-user cache directory. You can override the directory by specifying it in the
+ * {@code nashorn.typeInfo.cacheDir} directory. The maximum number of files is softly enforced by a task that
+ * cleans up the directory periodically on a separate thread. It is run after some delay after a new file is
+ * added to the cache. The default delay is 20 seconds, and can be set using the
+ * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word
+ * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is
+ * allowed to grow without limits.
  */
 public final class OptimisticTypesPersistence {
+    // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is
+    // dependent on the application; setting it to e.g. 20000 is probably good enough for most uses and will
+    // usually cap the cache directory to about 80MB presuming a 4kB filesystem allocation unit. There is one
+    // file per JavaScript function.
+    private static final int DEFAULT_MAX_FILES = 0;
+    // Constants for signifying that the cache should not be limited
+    private static final int UNLIMITED_FILES = -1;
+    // Maximum number of files that should be cached on disk. The maximum will be softly enforced.
+    private static final int MAX_FILES = getMaxFiles();
+    // Number of seconds to wait between adding a new file to the cache and running a cleanup process
+    private static final int DEFAULT_CLEANUP_DELAY = 20;
+    private static final int CLEANUP_DELAY = Math.max(0, Options.getIntProperty(
+            "nashorn.typeInfo.cleanupDelaySeconds", DEFAULT_CLEANUP_DELAY));
     // The name of the default subdirectory within the system cache directory where we store type info.
     private static final String DEFAULT_CACHE_SUBDIR_NAME = "com.oracle.java.NashornTypeInfo";
     // The directory where we cache type info
-    private static final File cacheDir = createCacheDir();
+    private static final File baseCacheDir = createBaseCacheDir();
+    private static final File cacheDir = createCacheDir(baseCacheDir);
     // In-process locks to make sure we don't have a cross-thread race condition manipulating any file.
     private static final Object[] locks = cacheDir == null ? null : createLockArray();
-
     // Only report one read/write error every minute
     private static final long ERROR_REPORT_THRESHOLD = 60000L;
 
     private static volatile long lastReportedError;
-
+    private static final AtomicBoolean scheduledCleanup;
+    private static final Timer cleanupTimer;
+    static {
+        if (baseCacheDir == null || MAX_FILES == UNLIMITED_FILES) {
+            scheduledCleanup = null;
+            cleanupTimer = null;
+        } else {
+            scheduledCleanup = new AtomicBoolean();
+            cleanupTimer = new Timer(true);
+        }
+    }
     /**
-     * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed to
-     * {@link #load(Object)} and {@link #store(Object, Map)} methods.
+     * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed
+     * to {@link #load(Object)} and {@link #store(Object, Map)} methods.
      * @param source the source where the function comes from
      * @param functionId the unique ID number of the function within the source
-     * @param paramTypes the types of the function parameters (as persistence is per parameter type specialization).
+     * @param paramTypes the types of the function parameters (as persistence is per parameter type
+     * specialization).
      * @return an opaque descriptor for the persistence location. Can be null if persistence is disabled.
      */
     public static Object getLocationDescriptor(final Source source, final int functionId, final Type[] paramTypes) {
@@ -82,7 +128,8 @@
         final StringBuilder b = new StringBuilder(48);
         // Base64-encode the digest of the source, and append the function id.
         b.append(source.getDigest()).append('-').append(functionId);
-        // Finally, if this is a parameter-type specialized version of the function, add the parameter types to the file name.
+        // Finally, if this is a parameter-type specialized version of the function, add the parameter types
+        // to the file name.
         if(paramTypes != null && paramTypes.length > 0) {
             b.append('-');
             for(final Type t: paramTypes) {
@@ -118,6 +165,11 @@
             @Override
             public Void run() {
                 synchronized(getFileLock(file)) {
+                    if (!file.exists()) {
+                        // If the file already exists, we aren't increasing the number of cached files, so
+                        // don't schedule cleanup.
+                        scheduleCleanup();
+                    }
                     try (final FileOutputStream out = new FileOutputStream(file)) {
                         out.getChannel().lock(); // lock exclusive
                         final DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out));
@@ -174,19 +226,19 @@
         }
     }
 
-    private static File createCacheDir() {
-        if(Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
+    private static File createBaseCacheDir() {
+        if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
             return null;
         }
         try {
-            return createCacheDirPrivileged();
+            return createBaseCacheDirPrivileged();
         } catch(final Exception e) {
             getLogger().warning("Failed to create cache dir", e);
             return null;
         }
     }
 
-    private static File createCacheDirPrivileged() {
+    private static File createBaseCacheDirPrivileged() {
         return AccessController.doPrivileged(new PrivilegedAction<File>() {
             @Override
             public File run() {
@@ -195,14 +247,35 @@
                 if(explicitDir != null) {
                     dir = new File(explicitDir);
                 } else {
-                    // When no directory is explicitly specified, get an operating system specific cache directory,
-                    // and create "com.oracle.java.NashornTypeInfo" in it.
+                    // When no directory is explicitly specified, get an operating system specific cache
+                    // directory, and create "com.oracle.java.NashornTypeInfo" in it.
                     final File systemCacheDir = getSystemCacheDir();
                     dir = new File(systemCacheDir, DEFAULT_CACHE_SUBDIR_NAME);
                     if (isSymbolicLink(dir)) {
                         return null;
                     }
                 }
+                return dir;
+            }
+        });
+    }
+
+    private static File createCacheDir(final File baseDir) {
+        if (baseDir == null) {
+            return null;
+        }
+        try {
+            return createCacheDirPrivileged(baseDir);
+        } catch(final Exception e) {
+            getLogger().warning("Failed to create cache dir", e);
+            return null;
+        }
+    }
+
+    private static File createCacheDirPrivileged(final File baseDir) {
+        return AccessController.doPrivileged(new PrivilegedAction<File>() {
+            @Override
+            public File run() {
                 final String versionDirName;
                 try {
                     versionDirName = getVersionDirName();
@@ -210,12 +283,12 @@
                     getLogger().warning("Failed to calculate version dir name", e);
                     return null;
                 }
-                final File versionDir = new File(dir, versionDirName);
+                final File versionDir = new File(baseDir, versionDirName);
                 if (isSymbolicLink(versionDir)) {
                     return null;
                 }
                 versionDir.mkdirs();
-                if(versionDir.isDirectory()) {
+                if (versionDir.isDirectory()) {
                     getLogger().info("Optimistic type persistence directory is " + versionDir);
                     return versionDir;
                 }
@@ -235,12 +308,12 @@
             // Mac OS X stores caches in ~/Library/Caches
             return new File(new File(System.getProperty("user.home"), "Library"), "Caches");
         } else if(os.startsWith("Windows")) {
-            // On Windows, temp directory is the best approximation of a cache directory, as its contents persist across
-            // reboots and various cleanup utilities know about it. java.io.tmpdir normally points to a user-specific
-            // temp directory, %HOME%\LocalSettings\Temp.
+            // On Windows, temp directory is the best approximation of a cache directory, as its contents
+            // persist across reboots and various cleanup utilities know about it. java.io.tmpdir normally
+            // points to a user-specific temp directory, %HOME%\LocalSettings\Temp.
             return new File(System.getProperty("java.io.tmpdir"));
         } else {
-            // In all other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache"
+            // In other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache"
             return new File(System.getProperty("user.home"), ".cache");
         }
     }
@@ -278,7 +351,8 @@
             final int packageNameLen = className.lastIndexOf('.');
             final String dirStr = fileStr.substring(0, fileStr.length() - packageNameLen - 1);
             final File dir = new File(dirStr);
-            return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(dir, 0L)));
+            return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(
+                    dir, 0L)));
         } else {
             throw new AssertionError();
         }
@@ -335,4 +409,108 @@
             return DebugLogger.DISABLED_LOGGER;
         }
     }
+
+    private static void scheduleCleanup() {
+        if (MAX_FILES != UNLIMITED_FILES && scheduledCleanup.compareAndSet(false, true)) {
+            cleanupTimer.schedule(new TimerTask() {
+                @Override
+                public void run() {
+                    scheduledCleanup.set(false);
+                    try {
+                        doCleanup();
+                    } catch (final IOException e) {
+                        // Ignore it. While this is unfortunate, we don't have good facility for reporting
+                        // this, as we're running in a thread that has no access to Context, so we can't grab
+                        // a DebugLogger.
+                    }
+                }
+            }, TimeUnit.SECONDS.toMillis(CLEANUP_DELAY));
+        }
+    }
+
+    private static void doCleanup() throws IOException {
+        final long start = System.nanoTime();
+        final Path[] files = getAllRegularFilesInLastModifiedOrder();
+        final int nFiles = files.length;
+        final int filesToDelete = Math.max(0, nFiles - MAX_FILES);
+        int filesDeleted = 0;
+        for (int i = 0; i < nFiles && filesDeleted < filesToDelete; ++i) {
+            try {
+                Files.deleteIfExists(files[i]);
+                // Even if it didn't exist, we increment filesDeleted; it existed a moment earlier; something
+                // else deleted it for us; that's okay with us.
+                filesDeleted++;
+            } catch (final Exception e) {
+                // does not increase filesDeleted
+            }
+            files[i] = null; // gc eligible
+        };
+        final long duration = System.nanoTime() - start;
+    }
+
+    private static Path[] getAllRegularFilesInLastModifiedOrder() throws IOException {
+        try (final Stream<Path> filesStream = Files.walk(baseCacheDir.toPath())) {
+            // TODO: rewrite below once we can use JDK8 syntactic constructs
+            return filesStream
+            .filter(new Predicate<Path>() {
+                @Override
+                public boolean test(final Path path) {
+                    return !Files.isDirectory(path);
+                };
+            })
+            .map(new Function<Path, PathAndTime>() {
+                @Override
+                public PathAndTime apply(final Path path) {
+                    return new PathAndTime(path);
+                }
+            })
+            .sorted()
+            .map(new Function<PathAndTime, Path>() {
+                @Override
+                public Path apply(final PathAndTime pathAndTime) {
+                    return pathAndTime.path;
+                }
+            })
+            .toArray(new IntFunction<Path[]>() { // Replace with Path::new
+                @Override
+                public Path[] apply(final int length) {
+                    return new Path[length];
+                }
+            });
+        }
+    }
+
+    private static class PathAndTime implements Comparable<PathAndTime> {
+        private final Path path;
+        private final long time;
+
+        PathAndTime(final Path path) {
+            this.path = path;
+            this.time = getTime(path);
+        }
+
+        @Override
+        public int compareTo(final PathAndTime other) {
+            return Long.compare(time, other.time);
+        }
+
+        private static long getTime(final Path path) {
+            try {
+                return Files.getLastModifiedTime(path).toMillis();
+            } catch (IOException e) {
+                // All files for which we can't retrieve the last modified date will be considered oldest.
+                return -1L;
+            }
+        }
+    }
+
+    private static int getMaxFiles() {
+        final String str = Options.getStringProperty("nashorn.typeInfo.maxFiles", null);
+        if (str == null) {
+            return DEFAULT_MAX_FILES;
+        } else if ("unlimited".equals(str)) {
+            return UNLIMITED_FILES;
+        }
+        return Math.max(0, Integer.parseInt(str));
+    }
 }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/TypeEvaluator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -108,7 +108,7 @@
 
         // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed
         // integer).
-        final Object value = property.getObjectValue(owner, owner);
+        final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner);
         if (value == ScriptRuntime.UNDEFINED) {
             return null;
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/types/Type.java	Wed Jul 05 20:00:07 2017 +0200
@@ -333,7 +333,7 @@
      */
     public static Map<Integer, Type> readTypeMap(final DataInput input) throws IOException {
         final int size = input.readInt();
-        if (size == 0) {
+        if (size <= 0) {
             return null;
         }
         final Map<Integer, Type> map = new TreeMap<>();
@@ -345,7 +345,7 @@
                 case 'L': type = Type.OBJECT; break;
                 case 'D': type = Type.NUMBER; break;
                 case 'J': type = Type.LONG; break;
-                default: throw new AssertionError();
+                default: continue;
             }
             map.put(pp, type);
         }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -138,10 +138,6 @@
     /** Last token of function. **/
     private final long lastToken;
 
-    /** Declared symbols in this function node */
-    @Ignore
-    private final Set<Symbol> declaredSymbols;
-
     /** Method's namespace. */
     private final Namespace namespace;
 
@@ -330,7 +326,6 @@
         this.lastToken        = token;
         this.namespace        = namespace;
         this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
-        this.declaredSymbols  = new HashSet<>();
         this.flags            = flags;
         this.compileUnit      = null;
         this.body             = null;
@@ -369,7 +364,6 @@
         this.id              = functionNode.id;
         this.ident           = functionNode.ident;
         this.namespace       = functionNode.namespace;
-        this.declaredSymbols = functionNode.declaredSymbols;
         this.kind            = functionNode.kind;
         this.firstToken      = functionNode.firstToken;
     }
@@ -724,24 +718,6 @@
     }
 
     /**
-     * Return a set of symbols declared in this function node. This
-     * is only relevant after Attr, otherwise it will be an empty
-     * set as no symbols have been introduced
-     * @return set of declared symbols in function
-     */
-    public Set<Symbol> getDeclaredSymbols() {
-        return Collections.unmodifiableSet(declaredSymbols);
-    }
-
-    /**
-     * Add a declared symbol to this function node
-     * @param symbol symbol that is declared
-     */
-    public void addDeclaredSymbol(final Symbol symbol) {
-        declaredSymbols.add(symbol);
-    }
-
-    /**
      * Get the function body
      * @return the function body
      */
@@ -970,13 +946,13 @@
     }
 
     /**
-     * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
+     * Check if this function should have all its variables in its own scope. Split sub-functions, and
      * functions having with and/or eval blocks are such.
      *
      * @return true if all variables should be in scope
      */
     public boolean allVarsInScope() {
-        return isProgram() || getFlag(HAS_ALL_VARS_IN_SCOPE);
+        return getFlag(HAS_ALL_VARS_IN_SCOPE);
     }
 
     /**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -46,6 +46,8 @@
     private static final int INITIALIZED_HERE  = 1 << 1;
     private static final int FUNCTION          = 1 << 2;
     private static final int FUTURESTRICT_NAME = 1 << 3;
+    private static final int IS_DECLARED_HERE  = 1 << 4;
+    private static final int IS_DEAD           = 1 << 5;
 
     /** Identifier. */
     private final String name;
@@ -247,6 +249,45 @@
     }
 
     /**
+     * Is this a LET or CONST identifier used before its declaration?
+     *
+     * @return true if identifier is dead
+     */
+    public boolean isDead() {
+        return (flags & IS_DEAD) != 0;
+    }
+
+    /**
+     * Flag this IdentNode as a LET or CONST identifier used before its declaration.
+     *
+     * @return a new IdentNode equivalent to this but marked as dead.
+     */
+    public IdentNode markDead() {
+        return new IdentNode(this, name, type, flags | IS_DEAD, programPoint, conversion);
+    }
+
+    /**
+     * Is this IdentNode declared here?
+     *
+     * @return true if identifier is declared here
+     */
+    public boolean isDeclaredHere() {
+        return (flags & IS_DECLARED_HERE) != 0;
+    }
+
+    /**
+     * Flag this IdentNode as being declared here.
+     *
+     * @return a new IdentNode equivalent to this but marked as declared here.
+     */
+    public IdentNode setIsDeclaredHere() {
+        if (isDeclaredHere()) {
+            return this;
+        }
+        return new IdentNode(this, name, type, flags | IS_DECLARED_HERE, programPoint, conversion);
+    }
+
+    /**
      * Check if the name of this IdentNode is same as that of a compile-time property (currently __DIR__, __FILE__, and
      * __LINE__).
      *
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Symbol.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Symbol.java	Wed Jul 05 20:00:07 2017 +0200
@@ -54,17 +54,17 @@
     public static final int IS_VAR      = 2;
     /** Is this a parameter */
     public static final int IS_PARAM    = 3;
-    /** Is this a constant */
-    public static final int IS_CONSTANT = 4;
     /** Mask for kind flags */
-    public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits
+    public static final int KINDMASK = (1 << 2) - 1; // Kinds are represented by lower two bits
 
     /** Is this symbol in scope */
-    public static final int IS_SCOPE                = 1 <<  3;
+    public static final int IS_SCOPE                = 1 <<  2;
     /** Is this a this symbol */
-    public static final int IS_THIS                 = 1 <<  4;
+    public static final int IS_THIS                 = 1 <<  3;
     /** Is this a let */
-    public static final int IS_LET                  = 1 <<  5;
+    public static final int IS_LET                  = 1 <<  4;
+    /** Is this a const */
+    public static final int IS_CONST                = 1 <<  5;
     /** Is this an internal symbol, never represented explicitly in source code */
     public static final int IS_INTERNAL             = 1 <<  6;
     /** Is this a function self-reference symbol */
@@ -83,6 +83,8 @@
     public static final int HAS_DOUBLE_VALUE        = 1 << 13;
     /** Is this symbol known to store an object value ? */
     public static final int HAS_OBJECT_VALUE        = 1 << 14;
+    /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
+    public static final int HAS_BEEN_DECLARED       = 1 << 15;
 
     /** Null or name identifying symbol. */
     private final String name;
@@ -184,14 +186,17 @@
             sb.append(" global");
             break;
         case IS_VAR:
-            sb.append(" var");
+            if (isConst()) {
+                sb.append(" const");
+            } else if (isLet()) {
+                sb.append(" let");
+            } else {
+                sb.append(" var");
+            }
             break;
         case IS_PARAM:
             sb.append(" param");
             break;
-        case IS_CONSTANT:
-            sb.append(" const");
-            break;
         default:
             break;
         }
@@ -204,10 +209,6 @@
             sb.append(" internal");
         }
 
-        if (isLet()) {
-            sb.append(" let");
-        }
-
         if (isThis()) {
             sb.append(" this");
         }
@@ -410,8 +411,8 @@
      * Check if this symbol is a constant
      * @return true if a constant
      */
-    public boolean isConstant() {
-        return (flags & KINDMASK) == IS_CONSTANT;
+    public boolean isConst() {
+        return (flags & IS_CONST) != 0;
     }
 
     /**
@@ -440,15 +441,6 @@
     }
 
     /**
-     * Flag this symbol as a let
-     */
-    public void setIsLet() {
-        if (!isLet()) {
-            flags |= IS_LET;
-        }
-    }
-
-    /**
      * Flag this symbol as a function's self-referencing symbol.
      * @return true if this symbol as a function's self-referencing symbol.
      */
@@ -456,6 +448,20 @@
         return (flags & IS_FUNCTION_SELF) != 0;
     }
 
+    public boolean isBlockScoped() {
+        return isLet() || isConst();
+    }
+
+    public boolean hasBeenDeclared() {
+        return (flags & HAS_BEEN_DECLARED) != 0;
+    }
+
+    public void setHasBeenDeclared() {
+        if (!hasBeenDeclared()) {
+            flags |= HAS_BEEN_DECLARED;
+        }
+    }
+
     /**
      * Get the index of the field used to store this symbol, should it be an AccessorProperty
      * and get allocated in a JO-prefixed ScriptObject subclass.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/VarNode.java	Wed Jul 05 20:00:07 2017 +0200
@@ -27,6 +27,7 @@
 
 import jdk.nashorn.internal.ir.annotations.Immutable;
 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.Token;
 
 /**
  * Node represents a var/let declaration.
@@ -43,12 +44,18 @@
     private final int flags;
 
     /** Flag that determines if this function node is a statement */
-    public static final int IS_STATEMENT = 1 << 0;
+    public static final int IS_STATEMENT                 = 1 << 0;
+
+    /** Flag for ES6 LET declaration */
+    public static final int IS_LET                       = 1 << 1;
+
+    /** Flag for ES6 CONST declaration */
+    public static final int IS_CONST                     = 1 << 2;
 
     /** Flag that determines if this is the last function declaration in a function
      *  This is used to micro optimize the placement of return value assignments for
      *  a program node */
-    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1;
+    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 3;
 
     /**
      * Constructor
@@ -109,6 +116,43 @@
     }
 
     /**
+     * Is this a VAR node block scoped? This returns true for ECMAScript 6 LET and CONST nodes.
+     * @return true if an ES6 LET or CONST node
+     */
+    public boolean isBlockScoped() {
+        return getFlag(IS_LET) || getFlag(IS_CONST);
+    }
+
+    /**
+     * Is this an ECMAScript 6 LET node?
+     * @return true if LET node
+     */
+    public boolean isLet() {
+        return getFlag(IS_LET);
+    }
+
+    /**
+     * Is this an ECMAScript 6 CONST node?
+     * @return true if CONST node
+     */
+    public boolean isConst() {
+        return getFlag(IS_CONST);
+    }
+
+    /**
+     * Return the flags to use for symbols for this declaration.
+     * @return the symbol flags
+     */
+    public int getSymbolFlags() {
+        if (isLet()) {
+            return Symbol.IS_VAR | Symbol.IS_LET;
+        } else if (isConst()) {
+            return Symbol.IS_VAR | Symbol.IS_CONST;
+        }
+        return Symbol.IS_VAR;
+    }
+
+    /**
      * Does this variable declaration have an init value
      * @return true if an init exists, false otherwise
      */
@@ -139,7 +183,7 @@
 
     @Override
     public void toString(final StringBuilder sb, final boolean printType) {
-        sb.append("var ");
+        sb.append(Token.descType(getToken()).getName()).append(' ');
         name.toString(sb, printType);
 
         if (init != null) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Jul 05 20:00:07 2017 +0200
@@ -45,6 +45,7 @@
 import static jdk.nashorn.internal.parser.TokenType.IF;
 import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
 import static jdk.nashorn.internal.parser.TokenType.LBRACE;
+import static jdk.nashorn.internal.parser.TokenType.LET;
 import static jdk.nashorn.internal.parser.TokenType.LPAREN;
 import static jdk.nashorn.internal.parser.TokenType.RBRACE;
 import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
@@ -579,6 +580,10 @@
         }
     }
 
+    private boolean useBlockScope() {
+        return env._es6;
+    }
+
     private static boolean isArguments(final String name) {
         return ARGUMENTS_NAME.equals(name);
     }
@@ -694,9 +699,20 @@
             FunctionNode.Kind.SCRIPT,
             functionLine);
 
+        // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations.
+        final int startLine = start;
+        Block outer = useBlockScope() ? newBlock() : null;
         functionDeclarations = new ArrayList<>();
-        sourceElements(allowPropertyFunction);
-        addFunctionDeclarations(script);
+
+        try {
+            sourceElements(allowPropertyFunction);
+            addFunctionDeclarations(script);
+        } finally {
+            if (outer != null) {
+                outer = restoreBlock(outer);
+                appendStatement(new BlockStatement(startLine, outer));
+            }
+        }
         functionDeclarations = null;
 
         expect(EOF);
@@ -868,7 +884,7 @@
             block();
             break;
         case VAR:
-            variableStatement(true);
+            variableStatement(type, true);
             break;
         case SEMICOLON:
             emptyStatement();
@@ -918,8 +934,12 @@
             expect(SEMICOLON);
             break;
         default:
+            if (useBlockScope() && (type == LET || type == CONST)) {
+                variableStatement(type, true);
+                break;
+            }
             if (env._const_as_var && type == CONST) {
-                variableStatement(true);
+                variableStatement(TokenType.VAR, true);
                 break;
             }
 
@@ -1035,11 +1055,17 @@
      * Parse a VAR statement.
      * @param isStatement True if a statement (not used in a FOR.)
      */
-    private List<VarNode> variableStatement(final boolean isStatement) {
+    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
         // VAR tested in caller.
         next();
 
         final List<VarNode> vars = new ArrayList<>();
+        int varFlags = VarNode.IS_STATEMENT;
+        if (varType == LET) {
+            varFlags |= VarNode.IS_LET;
+        } else if (varType == CONST) {
+            varFlags |= VarNode.IS_CONST;
+        }
 
         while (true) {
             // Get starting token.
@@ -1063,10 +1089,12 @@
                 } finally {
                     defaultNames.pop();
                 }
+            } else if (varType == CONST) {
+                throw error(AbstractParser.message("missing.const.assignment", name.getName()));
             }
 
             // Allocate var node.
-            final VarNode var = new VarNode(varLine, varToken, finish, name, init);
+            final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
             vars.add(var);
             appendStatement(var);
 
@@ -1180,9 +1208,12 @@
      * Parse a FOR statement.
      */
     private void forStatement() {
+        // When ES6 for-let is enabled we create a container block to capture the LET.
+        final int startLine = start;
+        Block outer = useBlockScope() ? newBlock() : null;
+
         // Create FOR node, capturing FOR token.
         ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR);
-
         lc.push(forNode);
 
         try {
@@ -1203,14 +1234,19 @@
             switch (type) {
             case VAR:
                 // Var statements captured in for outer block.
-                vars = variableStatement(false);
+                vars = variableStatement(type, false);
                 break;
             case SEMICOLON:
                 break;
             default:
+                if (useBlockScope() && (type == LET || type == CONST)) {
+                    // LET/CONST captured in container block created above.
+                    vars = variableStatement(type, false);
+                    break;
+                }
                 if (env._const_as_var && type == CONST) {
                     // Var statements captured in for outer block.
-                    vars = variableStatement(false);
+                    vars = variableStatement(TokenType.VAR, false);
                     break;
                 }
 
@@ -1290,8 +1326,13 @@
             appendStatement(forNode);
         } finally {
             lc.pop(forNode);
+            if (outer != null) {
+                outer.setFinish(forNode.getFinish());
+                outer = restoreBlock(outer);
+                appendStatement(new BlockStatement(startLine, outer));
+            }
         }
-     }
+    }
 
     /**
      * ... IterationStatement :
@@ -1722,7 +1763,7 @@
         }
     }
 
-   /**
+    /**
      * ThrowStatement :
      *      throw Expression ; // [no LineTerminator here]
      *
@@ -2609,7 +2650,7 @@
         FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine);
 
         if (isStatement) {
-            if (topLevel) {
+            if (topLevel || useBlockScope()) {
                 functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
             } else if (isStrictMode) {
                 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
@@ -2661,9 +2702,16 @@
         }
 
         if (isStatement) {
-            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
+            int varFlags = VarNode.IS_STATEMENT;
+            if (!topLevel && useBlockScope()) {
+                // mark ES6 block functions as lexically scoped
+                varFlags |= VarNode.IS_LET;
+            }
+            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags);
             if (topLevel) {
                 functionDeclarations.add(varNode);
+            } else if (useBlockScope()) {
+                prependStatement(varNode); // Hoist to beginning of current block
             } else {
                 appendStatement(varNode);
             }
@@ -2838,7 +2886,6 @@
     }
 
     private void addFunctionDeclarations(final FunctionNode functionNode) {
-        assert lc.peek() == lc.getFunctionBody(functionNode);
         VarNode lastDecl = null;
         for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
             Statement decl = functionDeclarations.get(i);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Jul 05 20:00:07 2017 +0200
@@ -549,6 +549,8 @@
                 type == Object.class :
                 "invalid getter type " + type + " for " + getKey();
 
+        checkUndeclared();
+
         //all this does is add a return value filter for object fields only
         final MethodHandle[] getterCache = GETTER_CACHE;
         final MethodHandle cachedGetter = getterCache[i];
@@ -579,6 +581,8 @@
             return getOptimisticPrimitiveGetter(type, programPoint);
         }
 
+        checkUndeclared();
+
         return debug(
             createGetter(
                 getCurrentType(),
@@ -608,6 +612,13 @@
         return newMap;
     }
 
+    private void checkUndeclared() {
+        if ((getFlags() & NEEDS_DECLARATION) != 0) {
+            // a lexically defined variable that hasn't seen its declaration - throw ReferenceError
+            throw ECMAErrors.referenceError("not.defined", getKey());
+        }
+    }
+
     // the final three arguments are for debug printout purposes only
     @SuppressWarnings("unused")
     private static Object replaceMap(final Object sobj, final PropertyMap newMap) {
@@ -635,13 +646,14 @@
 
     @Override
     public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
-        final int      i       = getAccessorTypeIndex(type);
-        final int      ci      = isUndefined() ? -1 : getAccessorTypeIndex(getCurrentType());
-        final Class<?> forType = isUndefined() ? type : getCurrentType();
+        checkUndeclared();
+
+        final int typeIndex        = getAccessorTypeIndex(type);
+        final int currentTypeIndex = getAccessorTypeIndex(getCurrentType());
 
         //if we are asking for an object setter, but are still a primitive type, we might try to box it
         MethodHandle mh;
-        if (needsInvalidator(i, ci)) {
+        if (needsInvalidator(typeIndex, currentTypeIndex)) {
             final Property     newProperty = getWiderProperty(type);
             final PropertyMap  newMap      = getWiderMap(currentMap, newProperty);
 
@@ -652,6 +664,7 @@
                  mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh);
             }
         } else {
+            final Class<?> forType = isUndefined() ? type : getCurrentType();
             mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type);
         }
 
@@ -692,11 +705,12 @@
         if (OBJECT_FIELDS_ONLY) {
             return false;
         }
-        return getCurrentType() != Object.class && (isConfigurable() || isWritable());
+        // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
+        return getCurrentType() == null || (getCurrentType() != Object.class && (isConfigurable() || isWritable()));
     }
 
-    private boolean needsInvalidator(final int ti, final int fti) {
-        return canChangeType() && ti > fti;
+    private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) {
+        return canChangeType() && typeIndex > currentTypeIndex;
     }
 
     @Override
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java	Wed Jul 05 20:00:07 2017 +0200
@@ -1132,7 +1132,7 @@
         if (storedScript == null) {
             functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
 
-            if (errors.hasErrors()) {
+            if (errMan.hasErrors()) {
                 return null;
             }
 
@@ -1162,9 +1162,13 @@
                     env,
                     installer,
                     source,
+                    errMan,
                     strict | functionNode.isStrict());
 
             final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
+            if (errMan.hasErrors()) {
+                return null;
+            }
             script = compiledFunction.getRootClass();
             compiler.persistClassInfo(cacheKey, compiledFunction);
         } else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/FindProperty.java	Wed Jul 05 20:00:07 2017 +0200
@@ -58,6 +58,18 @@
     }
 
     /**
+     * Return a copy of this FindProperty with a different property.
+     *
+     * @param newProperty the new property
+     * @return the new FindProperty instance
+     */
+    public FindProperty replaceProperty(final Property newProperty) {
+        assert this.property.getKey().equals(newProperty.getKey());
+        assert this.property.getSlot() == newProperty.getSlot();
+        return new FindProperty(self, prototype, newProperty);
+    }
+
+    /**
      * Ask for a getter that returns the given type. The type has nothing to do with the
      * internal representation of the property. It may be an Object (boxing primitives) or
      * a primitive (primitive fields with -Dnashorn.fields.dual=true)
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Wed Jul 05 20:00:07 2017 +0200
@@ -938,11 +938,8 @@
      * @return double
      */
     public static int toInt32Optimistic(final Object obj, final int programPoint) {
-        if (obj != null) {
-            final Class<?> clz = obj.getClass();
-            if (clz == Integer.class) {
-                return ((Integer)obj).intValue();
-            }
+        if (obj != null && obj.getClass() == Integer.class) {
+            return ((Integer)obj).intValue();
         }
         throw new UnwarrantedOptimismException(obj, programPoint);
     }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Wed Jul 05 20:00:07 2017 +0200
@@ -191,19 +191,20 @@
     }
 
     /**
-     * Returns the argument value as an int. If the argument is not a Number object that can be exactly represented as
-     * an int, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
-     * can use it. See {code CodeGenerator.ENSURE_INT}.
+     * Returns the argument value as an int. If the argument is not a wrapper for a primitive numeric type
+     * with a value that can be exactly represented as an int, throw an {@link UnwarrantedOptimismException}.
+     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_INT}.
      * @param arg the original argument.
      * @param programPoint the program point used in the exception
      * @return the value of the argument as an int.
-     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as an int.
+     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
+     * a value that can be exactly represented as an int.
      */
     public static int ensureInt(final Object arg, final int programPoint) {
         // NOTE: this doesn't delegate to ensureInt(double, int) as in that case if arg were a Long, it would throw a
         // (potentially imprecise) Double in the UnwarrantedOptimismException. This way, it will put the correct valued
         // Long into the exception.
-        if (arg instanceof Number) {
+        if (isPrimitiveNumberWrapper(arg)) {
             final double d = ((Number)arg).doubleValue();
             if (JSType.isRepresentableAsInt(d) && !JSType.isNegativeZero(d)) {
                 return (int)d;
@@ -212,6 +213,15 @@
         throw new UnwarrantedOptimismException(arg, programPoint);
     }
 
+    private static boolean isPrimitiveNumberWrapper(final Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        final Class<?> c = obj.getClass();
+        return c == Integer.class || c == Double.class || c == Long.class ||
+               c ==   Float.class || c ==  Short.class || c == Byte.class;
+    }
+
     @SuppressWarnings("unused")
     private static int ensureInt(final boolean arg, final int programPoint) {
         throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
@@ -236,35 +246,40 @@
     }
 
     /**
-     * Returns the argument value as a long. If the argument is not a Number object that can be exactly represented as
-     * a long, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
-     * can use it. See {code CodeGenerator.ENSURE_LONG}.
+     * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type
+     * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}.
+     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}.
      * @param arg the original argument.
      * @param programPoint the program point used in the exception
      * @return the value of the argument as a long.
-     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long.
+     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
+     * a value that can be exactly represented as a long
      */
     public static long ensureLong(final Object arg, final int programPoint) {
-        if (arg instanceof Long) {
-            // Must check for Long separately, as Long.doubleValue() isn't precise.
-            return ((Long)arg).longValue();
-        } else if (arg instanceof Number) {
-            return ensureLong(((Number)arg).doubleValue(), programPoint);
+        if (arg != null) {
+            final Class<?> c = arg.getClass();
+            if (c == Long.class) {
+                // Must check for Long separately, as Long.doubleValue() isn't precise.
+                return ((Long)arg).longValue();
+            } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class ||
+                    c == Byte.class) {
+                return ensureLong(((Number)arg).doubleValue(), programPoint);
+            }
         }
         throw new UnwarrantedOptimismException(arg, programPoint);
     }
 
     /**
-     * Returns the argument value as a double. If the argument is not a Number object, throw an
-     * {@link UnwarrantedOptimismException}.This method is only public so that generated script code can use it. See
-     * {code CodeGenerator.ENSURE_NUMBER}.
+     * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type
+     * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
+     * can use it. See {code CodeGenerator.ENSURE_NUMBER}.
      * @param arg the original argument.
      * @param programPoint the program point used in the exception
      * @return the value of the argument as a double.
-     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long.
+     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type.
      */
     public static double ensureNumber(final Object arg, final int programPoint) {
-        if (arg instanceof Number) { // arg == null -> false
+        if (isPrimitiveNumberWrapper(arg)) {
             return ((Number)arg).doubleValue();
         }
         throw new UnwarrantedOptimismException(arg, programPoint);
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Property.java	Wed Jul 05 20:00:07 2017 +0200
@@ -82,11 +82,14 @@
      * is narrower than object, e.g. Math.PI which is declared
      * as a double
      */
-    public static final int IS_NASGEN_PRIMITIVE = 1 << 6;
+    public static final int IS_NASGEN_PRIMITIVE     = 1 << 6;
 
     /** Is this property bound to a receiver? This means get/set operations will be delegated to
      *  a statically defined object instead of the object passed as callsite parameter. */
-    public static final int IS_BOUND = 1 << 8;
+    public static final int IS_BOUND                = 1 << 7;
+
+    /** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */
+    public static final int NEEDS_DECLARATION       = 1 << 8;
 
     /** Property key. */
     private final String key;
@@ -287,6 +290,15 @@
     }
 
     /**
+     * Is this a LET or CONST property that needs to see its declaration before being usable?
+     *
+     * @return true if this is a block-scoped variable
+     */
+    public boolean needsDeclaration() {
+        return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION;
+    }
+
+    /**
      * Add more property flags to the property. Properties are immutable here,
      * so any property change that results in a larger flag set results in the
      * property being cloned. Use only the return value
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Jul 05 20:00:07 2017 +0200
@@ -394,6 +394,7 @@
                 context.getEnv(),
                 installer,
                 functionNode.getSource(),  // source
+                context.getErrorManager(),
                 isStrict() | functionNode.isStrict(), // is strict
                 true,       // is on demand
                 this,       // compiledFunction, i.e. this RecompilableScriptFunctionData
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Wed Jul 05 20:00:07 2017 +0200
@@ -94,6 +94,9 @@
     /** Use single Global instance per jsr223 engine instance. */
     public final boolean _global_per_engine;
 
+    /** Enable experimental ECMAScript 6 features. */
+    public final boolean _es6;
+
     /** Argument passed to compile only if optimistic compilation should take place */
     public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
 
@@ -258,6 +261,15 @@
         _version              = options.getBoolean("version");
         _verify_code          = options.getBoolean("verify.code");
 
+        final String language = options.getString("language");
+        if (language == null || language.equals("es5")) {
+            _es6 = false;
+        } else if (language.equals("es6")) {
+            _es6 = true;
+        } else {
+            throw new RuntimeException("Unsupported language: " + language);
+        }
+
         String dir = null;
         String func = null;
         final String pc = options.getString("print.code");
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Jul 05 20:00:07 2017 +0200
@@ -36,6 +36,7 @@
 import java.lang.invoke.MethodType;
 import java.lang.invoke.SwitchPoint;
 import java.util.Collections;
+
 import jdk.internal.dynalink.CallSiteDescriptor;
 import jdk.internal.dynalink.linker.GuardedInvocation;
 import jdk.internal.dynalink.linker.LinkRequest;
@@ -44,6 +45,9 @@
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.objects.Global;
 import jdk.nashorn.internal.objects.NativeFunction;
+import jdk.nashorn.internal.runtime.ScriptFunctionData;
+import jdk.nashorn.internal.runtime.ScriptObject;
+import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
 
@@ -621,6 +625,23 @@
             appliedType = appliedType.changeParameterType(1, Object.class);
         }
 
+        /*
+         * dropArgs is a synthetic method handle that contains any args that we need to
+         * get rid of that come after the arguments array in the apply case. We adapt
+         * the callsite to ask for 3 args only and then dropArguments on the method handle
+         * to make it fit the extraneous args.
+         */
+        MethodType dropArgs = MH.type(void.class);
+        if (isApply && !isFailedApplyToCall) {
+            final int pc = appliedType.parameterCount();
+            for (int i = 3; i < pc; i++) {
+                dropArgs = dropArgs.appendParameterTypes(appliedType.parameterType(i));
+            }
+            if (pc > 3) {
+                appliedType = appliedType.dropParameterTypes(3, pc);
+            }
+        }
+
         if (isApply || isFailedApplyToCall) {
             if (passesArgs) {
                 // R(this, args) => R(this, Object[])
@@ -702,6 +723,15 @@
         }
         inv = MH.dropArguments(inv, 0, applyFnType);
 
+        /*
+         * Dropargs can only be non-()V in the case of isApply && !isFailedApplyToCall, which
+         * is when we need to add arguments to the callsite to catch and ignore the synthetic
+         * extra args that someone has added to the command line.
+         */
+        for (int i = 0; i < dropArgs.parameterCount(); i++) {
+            inv = MH.dropArguments(inv, 4 + i, dropArgs.parameterType(i));
+        }
+
         MethodHandle guard = appliedInvocation.getGuard();
         // If the guard checks the value of "this" but we aren't passing thisArg, insert the default one
         if (!passesThis && guard.type().parameterCount() > 1) {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Jul 05 20:00:07 2017 +0200
@@ -158,6 +158,7 @@
 
     static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
     static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
+    static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
 
     private static final MethodHandle TRUNCATINGFILTER   = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
     private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
@@ -2027,6 +2028,22 @@
         return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
     }
 
+    // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
+    @SuppressWarnings("unused")
+    private void declareAndSet(final String key, final Object value) {
+        final PropertyMap map = getMap();
+        final FindProperty find = findProperty(key, false);
+        assert find != null;
+
+        final Property property = find.getProperty();
+        assert property != null;
+        assert property.needsDeclaration();
+
+        final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
+        setMap(newMap);
+        set(key, value, true);
+    }
+
     /**
      * Find the appropriate GETINDEX method for an invoke dynamic call.
      *
@@ -2140,7 +2157,7 @@
         }
 
         if (find != null) {
-            if (!find.getProperty().isWritable()) {
+            if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) {
                 // Existing, non-writable property
                 return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
             }
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Jul 05 20:00:07 2017 +0200
@@ -108,6 +108,11 @@
     public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
 
     /**
+     * Throws a reference error for an undefined variable.
+     */
+    public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
+
+    /**
      * Converts a switch tag value to a simple integer. deflt value if it can't.
      *
      * @param tag   Switch statement tag value.
@@ -382,6 +387,15 @@
     }
 
     /**
+     * Throws a reference error for an undefined variable.
+     *
+     * @param name the variable name
+     */
+    public static void throwReferenceError(final String name) {
+        throw referenceError("not.defined", name);
+    }
+
+    /**
      * Call a script function as a constructor with given args.
      *
      * @param target ScriptFunction object.
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Jul 05 20:00:07 2017 +0200
@@ -140,7 +140,29 @@
 
     private SetMethod createExistingPropertySetter() {
         final Property property = find.getProperty();
-        final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
+        final MethodHandle methodHandle;
+
+        if (NashornCallSiteDescriptor.isDeclaration(desc)) {
+            assert property.needsDeclaration();
+            // This is a LET or CONST being declared. The property is already there but flagged as needing declaration.
+            // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set
+            // method if the pre-callsite map is stable (which should be the case for function scopes except for
+            // non-strict functions containing eval() with var). Otherwise we have to use a slow setter that creates
+            // a new PropertyMap on the fly.
+            final PropertyMap oldMap = getMap();
+            final Property newProperty = property.removeFlags(Property.NEEDS_DECLARATION);
+            final PropertyMap newMap = oldMap.replaceProperty(property, newProperty);
+            final MethodHandle fastSetter = find.replaceProperty(newProperty).getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
+            final MethodHandle slowSetter = MH.insertArguments(ScriptObject.DECLARE_AND_SET, 1, getName()).asType(fastSetter.type());
+
+            // cas map used as guard, if true that means we can do the set fast
+            MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
+            casMap = MH.dropArguments(casMap, 1, type);
+            casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
+            methodHandle = MH.guardWithTest(casMap, fastSetter, slowSetter);
+        } else {
+            methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
+        }
 
         assert methodHandle != null;
         assert property     != null;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Wed Jul 05 20:00:07 2017 +0200
@@ -628,18 +628,20 @@
         Class<?> widest = Integer.class;
 
         for (final Object item : items) {
-            final Class<?> itemClass = item == null ? null : item.getClass();
+            if (item == null) {
+                return Object.class;
+            }
+            final Class<?> itemClass = item.getClass();
             if (itemClass == Long.class) {
                 if (widest == Integer.class) {
                     widest = Long.class;
                 }
-            } else if (itemClass == Double.class) {
+            } else if (itemClass == Double.class || itemClass == Float.class) {
                 if (widest == Integer.class || widest == Long.class) {
                     widest = Double.class;
                 }
-            } else if (!(item instanceof Number)) {
-                widest = Object.class;
-                break;
+            } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) {
+                return Object.class;
             }
         }
 
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Jul 05 20:00:07 2017 +0200
@@ -54,23 +54,25 @@
     public static final int CALLSITE_OPTIMISTIC    = 1 << 3;
     /** Is this really an apply that we try to call as a call? */
     public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;
+    /** Does this a callsite for a variable declaration? */
+    public static final int CALLSITE_DECLARE       = 1 << 5;
 
     /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
      * code where call sites have this flag set. */
-    public static final int CALLSITE_PROFILE        = 1 << 5;
+    public static final int CALLSITE_PROFILE         = 1 << 6;
     /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
      * call sites have this flag set. */
-    public static final int CALLSITE_TRACE          = 1 << 6;
+    public static final int CALLSITE_TRACE           = 1 << 7;
     /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
      * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
-    public static final int CALLSITE_TRACE_MISSES   = 1 << 7;
+    public static final int CALLSITE_TRACE_MISSES    = 1 << 8;
     /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
      * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
-    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 8;
+    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 9;
     /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
      * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
      * have this flag set. */
-    public static final int CALLSITE_TRACE_VALUES   = 1 << 9;
+    public static final int CALLSITE_TRACE_VALUES    = 1 << 10;
 
     //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
     //right now given the program points
@@ -82,10 +84,10 @@
      * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
      * trace/profile settings.
      */
-    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 10;
+    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 11;
 
     /**
-     * Maximum program point value. 22 bits should be enough for anyone
+     * Maximum program point value. 21 bits should be enough for anyone
      */
     public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1;
 
@@ -123,6 +125,9 @@
                 assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
                 sb.append("scope ");
             }
+            if ((flags & CALLSITE_DECLARE) != 0) {
+                sb.append("declare ");
+            }
         }
         if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
             sb.append("apply2call ");
@@ -329,6 +334,15 @@
     }
 
     /**
+     * Does this callsite contain a declaration for its target?
+     * @param desc descriptor
+     * @return true if contains declaration
+     */
+    public static boolean isDeclaration(final CallSiteDescriptor desc) {
+        return isFlag(desc, CALLSITE_DECLARE);
+    }
+
+    /**
      * Get a program point from a descriptor (must be optimistic)
      * @param desc descriptor
      * @return program point
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Messages.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -58,6 +58,7 @@
 parser.error.regex.repeated.flag=Repeated RegExp flag: {0}
 parser.error.regex.syntax={0}
 parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
+parser.error.missing.const.assignment=Missing assignment to constant "{0}"
 
 # strict mode error messages
 parser.error.strict.no.with="with" statement cannot be used in strict mode
@@ -162,6 +163,8 @@
 
 syntax.error.invalid.json=Invalid JSON: {0}
 syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
+syntax.error.redeclare.variable=Variable "{0}" has already been declared
+syntax.error.assign.constant=Assignment to constant "{0}"
 
 io.error.cant.write=cannot write "{0}"
 config.error.no.dest=no destination directory supplied
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/resources/Options.properties	Wed Jul 05 20:00:07 2017 +0200
@@ -329,6 +329,14 @@
     desc="Enable scripting features."   \
 }
 
+nashorn.option.language = {                      \
+    name="--language",                           \
+    type=String,                                 \
+    params=[es5|es6],                            \
+    default=es5,                                 \
+    desc="Specify ECMAScript language version."  \
+}
+
 nashorn.option.stdout = {                                                \
     name="--stdout",                                                     \
     is_undocumented=true,                                                \
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/tools/Shell.java	Wed Jul 05 20:00:07 2017 +0200
@@ -252,6 +252,15 @@
                     return COMPILATION_ERROR;
                 }
 
+                new Compiler(
+                       context,
+                       env,
+                       null, //null - pass no code installer - this is compile only
+                       functionNode.getSource(),
+                       context.getErrorManager(),
+                       env._strict | functionNode.isStrict()).
+                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
+
                 if (env._print_ast) {
                     context.getErr().println(new ASTWriter(functionNode));
                 }
@@ -260,14 +269,9 @@
                     context.getErr().println(new PrintVisitor(functionNode));
                 }
 
-                //null - pass no code installer - this is compile only
-                new Compiler(
-                       context,
-                       env,
-                       null,
-                       functionNode.getSource(),
-                       env._strict | functionNode.isStrict()).
-                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
+                if (errors.getNumberOfErrors() != 0) {
+                    return COMPILATION_ERROR;
+                }
             }
         } finally {
             env.getOut().flush();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8056129.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8056129: AtomicInteger is treated as primitive number with optimistic compilation
+ *
+ * @test
+ * @run
+ */
+
+var AtomicInteger = java.util.concurrent.atomic.AtomicInteger;
+
+function getAtomic() { 
+   return new AtomicInteger() 
+} 
+var x = getAtomic() 
+print(x instanceof AtomicInteger)
+
+var a = []
+a.push(x)
+var y = a[0]
+print(y instanceof AtomicInteger)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8056129.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,2 @@
+true
+true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8057019-2.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+/**
+ * this apply with extra arguments
+ * (with apply to call enabled)
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + 'JDK-8057019-payload.js');
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8057019-2.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,24 @@
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+TypeError: Function.prototype.apply expects an Array for second argument
+TypeError: Function.prototype.apply expects an Array for second argument
+TypeError: Function.prototype.apply expects an Array for second argument
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8057019-payload.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+/**
+ * this apply with extra arguments
+ *
+ * @subtest
+ */
+
+function func(x, y, z) {
+    print(x, y, z);
+}
+
+function g() {
+    func.apply(this, arguments);
+}
+function h() {
+    func.apply(this, arguments, 23);
+}
+function i() {
+    func.apply(this, arguments, 23, 4711);
+}
+function j() {
+    func.apply(this, arguments, 23, 4711, "apa", "dingo", "gorilla");
+}
+function k() {
+    func.apply(this, arguments, 23);
+}
+function l() {
+    func.apply(this, [23, "apa", "gorilla", "dingo"], 17);
+}
+function m() {
+    func.apply(this, [23, "apa", "gorilla", "dingo"]);
+}
+function n() {
+    func.apply(this, "significant");
+}
+
+g(1,2);
+g(1,2,3);
+g(1,2,3,4);
+
+h(1,2);
+h(1,2,3);
+h(1,2,3,4);
+
+i(1,2);
+i(1,2,3);
+i(1,2,3,4);
+
+j(1,2);
+j(1,2,3);
+j(1,2,3,4);
+
+k(1,2);
+k(1,2,3);
+k(1,2,3,4);
+
+l(1,2);
+l(1,2,3);
+l(1,2,3,4);
+
+m(1,2);
+m(1,2,3);
+m(1,2,3,4);
+
+try {
+    n(1,2);
+} catch (e) {
+    print(e);
+}
+try {
+    n(1,2,3);
+} catch (e) {
+    print(e);    
+}
+
+try {
+    n(1,2,3,4);
+} catch (e) {
+    print(e);   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8057019.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+/**
+ * this apply with extra arguments
+ * (turning off apply to call)
+ *
+ * @fork
+ * @option -Dnashorn.apply2call=false
+ * @test
+ * @run
+ */
+
+load(__DIR__ + 'JDK-8057019-payload.js');
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8057019.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,24 @@
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+1 2 undefined
+1 2 3
+1 2 3
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+23 apa gorilla
+TypeError: Function.prototype.apply expects an Array for second argument
+TypeError: Function.prototype.apply expects an Array for second argument
+TypeError: Function.prototype.apply expects an Array for second argument
--- a/nashorn/test/script/basic/apply_to_call/apply_to_call4.js.EXPECTED	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/script/basic/apply_to_call/apply_to_call4.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -15,8 +15,8 @@
 2.3
 3.4
 test 5 done
-a=object
-17
+a=number
+22
 undefined
 Now it's time for transforms
 19
--- a/nashorn/test/script/basic/compile-octane-normal.js	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/script/basic/compile-octane-normal.js	Wed Jul 05 20:00:07 2017 +0200
@@ -38,5 +38,5 @@
  */
 
 var fn  = __DIR__ + 'compile-octane.js';
-var url = "file://" + fn;
-loadWithNewGlobal(new java.net.URL(url));
+var url = new java.io.File(fn).toURL();
+loadWithNewGlobal(url);
--- a/nashorn/test/script/basic/compile-octane-splitter.js	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/script/basic/compile-octane-splitter.js	Wed Jul 05 20:00:07 2017 +0200
@@ -40,5 +40,5 @@
  */
 
 var fn  = __DIR__ + 'compile-octane.js';
-var url = "file://" + fn;
-loadWithNewGlobal(new java.net.URL(url));
+var url = new java.io.File(fn).toURL();
+loadWithNewGlobal(url);
--- a/nashorn/test/script/basic/compile-octane.js	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/script/basic/compile-octane.js	Wed Jul 05 20:00:07 2017 +0200
@@ -132,7 +132,7 @@
         str2 += " processing file: " + file + "...";
         print_if_verbose(str2);
         }
-        newGlobal.load("file://" + path + file);
+        newGlobal.load(new java.io.File(path + file).toURL());
     }
     }
     print("Done.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/block-function-decl.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+"use strict";
+
+{
+    // f is defined on block level
+    print(f);
+    f();
+    function f() {
+        print("in f");
+    }
+    print(f);
+    f();
+}
+
+try {
+    print(typeof f);
+    f();
+} catch (e) {
+    print(e);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/block-function-decl.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,10 @@
+function f() {
+        print("in f");
+    }
+in f
+function f() {
+        print("in f");
+    }
+in f
+undefined
+ReferenceError: "f" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-empty.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+try {
+    eval('"use strict";\n' +
+        'const x;\n');
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-empty.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+SyntaxError: test/script/basic/es6/const-empty.js#33:4<eval>@1:2:7 Missing assignment to constant "x"
+const x;
+       ^
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-reassign.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x = 1;\n');
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x++;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x--;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        '++x;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        '--x;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x += 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x *= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x /= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x %= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x |= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x &= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x ^= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x <<= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x >>= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'x >>>= 1;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
+
+try {
+    eval('"use strict";\n' +
+        'const x = 2;\n' +
+        'delete x;\n');
+    fail("const assignment didn't throw");
+} catch (e) {
+    print(e.name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-reassign.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,16 @@
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
+SyntaxError
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-redeclare.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+try {
+    eval('"use strict";\n' +
+         'const x = 2;\n' +
+         'const x = 2;\n');
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-redeclare.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+SyntaxError: test/script/basic/es6/const-redeclare.js#33:4<eval>@1:2:6 Variable "x" has already been declared
+const x = 2;
+      ^
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-self.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+const a = 1, b = a;
+
+print(a, b);
+
+try {
+    eval('"use strict";\n' +
+         'const a = a;\n');
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-self.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,2 @@
+1 1
+ReferenceError: "a" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-tdz.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+{
+    print("test 1");
+
+    function f() {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    f();
+    const a = 1;
+    f();
+}
+
+{
+    print("test 2");
+
+    function f() {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    f();
+    const a = 2;
+    f();
+}
+
+{
+    print("test 3");
+    {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    const a = 3;
+
+    {
+        print(a);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const-tdz.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,9 @@
+test 1
+ReferenceError: "a" is not defined
+1
+test 2
+ReferenceError: "a" is not defined
+2
+test 3
+ReferenceError: "a" is not defined
+3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+"use strict";
+
+const a = 2;
+const c = 2;
+print(a, c);
+
+function f(x) {
+    const a = 5;
+    const c = 10;
+    print(a, c);
+    if (x) {
+        const a = 42;
+        const c = 43;
+        print(a, c);
+    }
+    print(a, c);
+
+    function inner() {
+        (function() {
+            print(a, c);
+        })();
+    }
+    inner();
+}
+
+f(true);
+f(false);
+
+(function() {
+    (function() {
+        print(a, c);
+    })();
+})();
+
+function outer() {
+    print(a, c);
+}
+outer();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/const.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,10 @@
+2 2
+5 10
+42 43
+5 10
+5 10
+5 10
+5 10
+5 10
+2 2
+2 2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/for-let.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+for (let i = 0; i < 10; i++) {
+    print(i);
+}
+
+try {
+    print(i);
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/for-let.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,11 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+ReferenceError: "i" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-eval.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+function f() {
+    var a;
+    let b;
+    const c = 0;
+
+    print(a, b, c);
+
+    try {
+        eval("x = 1; print('x: ' + x);");
+        print("assignment to x succeeded");
+    } catch (e) {
+        print(e);
+    }
+    try {
+        eval("'use strict'; let z = 1; print('z: ' + z);");
+        print("assignment to z succeeded");
+        eval("print('z: ' + z);");
+    } catch (e) {
+        print(e);
+    }
+
+    try {
+        eval("a = 1; print(a);");
+        print("assignment to a succeeded");
+    } catch (e) {
+        print(e);
+    }
+    print("a: " + a);
+
+    try {
+        eval("b = 1; print('b: ' + b);");
+        print("assignment to b succeeded");
+    } catch (e) {
+        print(e);
+    }
+    print("b: " + b);
+
+    try {
+        eval("c = 1; print('c: ' + c);");
+        print("assignment to c succeeded");
+    } catch (e) {
+        print(e);
+    }
+    print("c: " + c);
+
+    eval("a = 2; let b = 3;");
+
+    try {
+        print(a, b, c);
+    } catch (e) {
+        print(e);
+    }
+
+    let x;
+
+    try {
+        print(a, b, c, x);
+    } catch (e) {
+        print(e);
+    }
+
+}
+
+f();
+
+print(typeof a, typeof b, typeof c, typeof x, typeof z);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-eval.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,16 @@
+undefined undefined 0
+ReferenceError: "x" is not defined
+z: 1
+assignment to z succeeded
+ReferenceError: "z" is not defined
+1
+assignment to a succeeded
+a: 1
+b: 1
+assignment to b succeeded
+b: 1
+TypeError: "c" is not a writable property of [object Object]
+c: 0
+2 1 0
+2 1 0 undefined
+undefined undefined undefined undefined undefined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-load-lib.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010, 2014, 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.
+ */
+
+/**
+ * @subtest
+ */
+
+"use strict";
+
+// var should be visible in other script, let and const not
+var a = 1;
+let b = 2;
+const c = 3;
+
+// top level function should be visible
+function top() {
+    print("top level function");
+}
+
+// block level function not visible outside script
+{
+    function block() {
+        print("block function");
+    }
+
+    top();
+    block();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-load.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+load(__DIR__ + "let-load-lib.js");
+
+{
+    let a = 20;
+    const c = 30;
+    print("print local defs: " + a, c);
+}
+
+print("imported var: " + a);
+try {
+    print("imported let: " + b);
+} catch (e) {
+    print(e);
+}
+
+try {
+    print("imported const: " + c);
+} catch (e) {
+    print(e);
+}
+
+top();
+
+try {
+    block();
+} catch (e) {
+    print(e);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-load.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,8 @@
+top level function
+block function
+print local defs: 20 30
+imported var: 1
+ReferenceError: "b" is not defined
+ReferenceError: "c" is not defined
+top level function
+ReferenceError: "block" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-nodeclare.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+try {
+    if (true) {
+        let x = 2;
+        print(x);
+    }
+    print(x);
+} catch (e) {
+    print(e);
+}
+
+
+try {
+    if (true) {
+        const x = 2;
+        print(x);
+    }
+    print(x);
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-nodeclare.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,4 @@
+2
+ReferenceError: "x" is not defined
+2
+ReferenceError: "x" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-redeclare.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+try {
+    eval('"use strict";\n' +
+         'let x = 2;\n' +
+         'let x = 2;\n');
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-redeclare.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,3 @@
+SyntaxError: test/script/basic/es6/let-redeclare.js#33:4<eval>@1:2:4 Variable "x" has already been declared
+let x = 2;
+    ^
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-self.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+let a, b = a;
+
+print(a, b);
+
+try {
+    eval('"use strict";\n' +
+         'let a = a;\n');
+} catch (e) {
+    print(e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-self.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,2 @@
+undefined undefined
+ReferenceError: "a" is not defined
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-tdz.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+{
+    print("test 1");
+
+    function f() {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    f();
+    let a = 1;
+    f();
+}
+
+{
+    print("test 2");
+
+    function f() {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    f();
+    let a = 2;
+    f();
+}
+
+{
+    print("test 3");
+
+    {
+        try {
+            print(a);
+        } catch (a) {
+            print(a);
+        }
+    }
+
+    let a = 3;
+
+    {
+        print(a);
+    }
+}
+
+{
+    print("test 4");
+    let a;
+
+    {
+        print(a);
+    }
+
+    a = 4;
+
+    {
+        print(a);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let-tdz.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,12 @@
+test 1
+ReferenceError: "a" is not defined
+1
+test 2
+ReferenceError: "a" is not defined
+2
+test 3
+ReferenceError: "a" is not defined
+3
+test 4
+undefined
+4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let.js	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8051889: Implement block scoping in symbol assignment and scope computation
+ *
+ * @test
+ * @run
+ * @option --language=es6 */
+
+"use strict";
+
+let a = 2;
+let c = 2;
+print(a, c);
+
+function f(x) {
+    let a = 5;
+    const c = 10;
+    print(a, c);
+    if (x) {
+        let a = 42;
+        const c = 43;
+        print(a, c);
+    }
+    print(a, c);
+
+    function inner() {
+        (function() {
+            print(a, c);
+        })();
+    }
+    inner();
+}
+
+f(true);
+f(false);
+
+(function() {
+    (function() {
+        print(a, c);
+    })();
+})();
+
+function outer() {
+    print(a, c);
+}
+outer();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/let.js.EXPECTED	Wed Jul 05 20:00:07 2017 +0200
@@ -0,0 +1,10 @@
+2 2
+5 10
+42 43
+5 10
+5 10
+5 10
+5 10
+5 10
+2 2
+2 2
--- a/nashorn/test/script/trusted/JDK-8006529.js	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/script/trusted/JDK-8006529.js	Wed Jul 05 20:00:07 2017 +0200
@@ -120,7 +120,7 @@
 
 var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
 var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
-var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, boolean.class);
+var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class);
 
 // compile(script) -- compiles a script specified as a string with its
 // source code, returns a jdk.nashorn.internal.ir.FunctionNode object
@@ -134,7 +134,7 @@
     var parser   = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
     var func     = parseMethod.invoke(parser);
 
-    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, false);
+    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false);
 
     return compileMethod.invoke(compiler, func, phases);
 };
--- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -98,11 +98,16 @@
             compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() {
                 @Override
                 public boolean exclude(final File file, final String content) {
-                    return content.indexOf("@negative") != -1;
+                    return content != null && content.contains("@negative");
                 }
             });
         }
-        compileTestSet(new File(TEST_BASIC_DIR), null);
+        compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() {
+            @Override
+            public boolean exclude(final File file, final String content) {
+                return file.getName().equals("es6");
+            }
+        });
         compileTestSet(new File(TEST_NODE_DIR, "node"), null);
         compileTestSet(new File(TEST_NODE_DIR, "src"), null);
     }
@@ -136,6 +141,9 @@
     private int skipped;
 
     private void compileJSDirectory(final File dir, final TestFilter filter) {
+        if (filter != null && filter.exclude(dir, null)) {
+            return;
+        }
         for (final File f : dir.listFiles()) {
             if (f.isDirectory()) {
                 compileJSDirectory(f, filter);
--- a/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java	Wed Jul 05 19:59:05 2017 +0200
+++ b/nashorn/test/src/jdk/nashorn/internal/parser/ParserTest.java	Wed Jul 05 20:00:07 2017 +0200
@@ -82,11 +82,16 @@
             parseTestSet(TEST262_SUITE_DIR, new TestFilter() {
                 @Override
                 public boolean exclude(final File file, final String content) {
-                    return content.indexOf("@negative") != -1;
+                    return content != null && content.contains("@negative");
                 }
             });
         }
-        parseTestSet(TEST_BASIC_DIR, null);
+        parseTestSet(TEST_BASIC_DIR,  new TestFilter() {
+            @Override
+            public boolean exclude(final File file, final String content) {
+                return file.getName().equals("es6");
+            }
+        });
     }
 
     private void parseTestSet(final String testSet, final TestFilter filter) {
@@ -120,6 +125,9 @@
     private int skipped;
 
     private void parseJSDirectory(final File dir, final TestFilter filter) {
+        if (filter != null && filter.exclude(dir, null)) {
+            return;
+        }
         for (final File f : dir.listFiles()) {
             if (f.isDirectory()) {
                 parseJSDirectory(f, filter);