Merge JDK-8145252-TLS13-branch
authorwetmore
Wed, 23 May 2018 09:33:37 -0700
branchJDK-8145252-TLS13-branch
changeset 56599 137a16d6d987
parent 56595 fa746939d740 (current diff)
parent 50237 ec52b4d094c0 (diff)
child 56600 58ad02eb44c3
Merge
test/jdk/java/lang/Character/Blocks.txt
test/jdk/java/lang/Character/CheckBlocks.java
test/jdk/java/lang/Character/TestISOControls.java
--- a/src/hotspot/os/windows/os_windows.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/os/windows/os_windows.cpp	Wed May 23 09:33:37 2018 -0700
@@ -1745,13 +1745,46 @@
   // value if total memory is larger than 4GB
   MEMORYSTATUSEX ms;
   ms.dwLength = sizeof(ms);
-  GlobalMemoryStatusEx(&ms);
-
-  st->print(", physical %uk", os::physical_memory() >> 10);
-  st->print("(%uk free)", os::available_memory() >> 10);
-
-  st->print(", swap %uk", ms.ullTotalPageFile >> 10);
-  st->print("(%uk free)", ms.ullAvailPageFile >> 10);
+  int r1 = GlobalMemoryStatusEx(&ms);
+
+  if (r1 != 0) {
+    st->print(", system-wide physical " INT64_FORMAT "M ",
+             (int64_t) ms.ullTotalPhys >> 20);
+    st->print("(" INT64_FORMAT "M free)\n", (int64_t) ms.ullAvailPhys >> 20);
+
+    st->print("TotalPageFile size " INT64_FORMAT "M ",
+             (int64_t) ms.ullTotalPageFile >> 20);
+    st->print("(AvailPageFile size " INT64_FORMAT "M)",
+             (int64_t) ms.ullAvailPageFile >> 20);
+
+    // on 32bit Total/AvailVirtual are interesting (show us how close we get to 2-4 GB per process borders)
+#if defined(_M_IX86)
+    st->print(", user-mode portion of virtual address-space " INT64_FORMAT "M ",
+             (int64_t) ms.ullTotalVirtual >> 20);
+    st->print("(" INT64_FORMAT "M free)", (int64_t) ms.ullAvailVirtual >> 20);
+#endif
+  } else {
+    st->print(", GlobalMemoryStatusEx did not succeed so we miss some memory values.");
+  }
+
+  // extended memory statistics for a process
+  PROCESS_MEMORY_COUNTERS_EX pmex;
+  ZeroMemory(&pmex, sizeof(PROCESS_MEMORY_COUNTERS_EX));
+  pmex.cb = sizeof(pmex);
+  int r2 = GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmex, sizeof(pmex));
+
+  if (r2 != 0) {
+    st->print("\ncurrent process WorkingSet (physical memory assigned to process): " INT64_FORMAT "M, ",
+             (int64_t) pmex.WorkingSetSize >> 20);
+    st->print("peak: " INT64_FORMAT "M\n", (int64_t) pmex.PeakWorkingSetSize >> 20);
+
+    st->print("current process commit charge (\"private bytes\"): " INT64_FORMAT "M, ",
+             (int64_t) pmex.PrivateUsage >> 20);
+    st->print("peak: " INT64_FORMAT "M", (int64_t) pmex.PeakPagefileUsage >> 20);
+  } else {
+    st->print("\nGetProcessMemoryInfo did not succeed so we miss some memory values.");
+  }
+
   st->cr();
 }
 
--- a/src/hotspot/share/classfile/stringTable.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/classfile/stringTable.cpp	Wed May 23 09:33:37 2018 -0700
@@ -434,7 +434,7 @@
 
 void StringTable::dump(outputStream* st, bool verbose) {
   if (!verbose) {
-    the_table()->print_table_statistics(st, "StringTable");
+    the_table()->print_table_statistics(st, "StringTable", string_object_no_keepalive);
   } else {
     Thread* THREAD = Thread::current();
     st->print_cr("VERSION: 1.1");
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp	Wed May 23 09:33:37 2018 -0700
@@ -332,6 +332,7 @@
   assert(age_node->acquired_by_self(), "invariant");
   assert(age_node != NULL, "invariant");
   age_node->set_retired_buffer(buffer);
+  control.increment_full();
   return insert_full_age_node(age_node, age_mspace, thread);
 }
 
@@ -631,6 +632,7 @@
 static void process_age_list(Processor& processor, JfrStorageAgeMspace* age_mspace, JfrAgeNode* head, size_t count) {
   assert(age_mspace != NULL, "invariant");
   assert(head != NULL, "invariant");
+  assert(count > 0, "invariant");
   JfrAgeNode* node = head;
   JfrAgeNode* last = NULL;
   while (node != NULL) {
@@ -669,7 +671,7 @@
     return 0;
   }
   size_t count;
-  JfrAgeNode* head;;
+  JfrAgeNode* head;
   {
     // fetch age list
     MutexLockerEx buffer_lock(JfrBuffer_lock, Mutex::_no_safepoint_check_flag);
@@ -678,6 +680,7 @@
     control.reset_full();
   }
   assert(head != NULL, "invariant");
+  assert(count > 0, "invariant");
   process_age_list(processor, age_mspace, head, count);
   return count;
 }
--- a/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/jfr/recorder/storage/jfrStorageControl.cpp	Wed May 23 09:33:37 2018 -0700
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "jfr/recorder/storage/jfrStorageControl.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/orderAccess.inline.hpp"
 
 // returns the updated value
@@ -69,22 +70,25 @@
   _to_disk = enable;
 }
 
-// concurrent with lax requirement
-
 size_t JfrStorageControl::full_count() const {
   return _full_count;
 }
 
+// mutexed access
 size_t JfrStorageControl::increment_full() {
-  return atomic_add(1, &_full_count);
+  assert(JfrBuffer_lock->owned_by_self(), "invariant");
+  return ++_full_count;
 }
 
 size_t JfrStorageControl::decrement_full() {
-  return atomic_dec(&_full_count);
+  assert(JfrBuffer_lock->owned_by_self(), "invariant");
+  assert(_full_count > 0, "invariant");
+  return --_full_count;
 }
 
 void JfrStorageControl::reset_full() {
-  Atomic::store((size_t)0, &_full_count);
+  assert(JfrBuffer_lock->owned_by_self(), "invariant");
+  _full_count = 0;
 }
 
 bool JfrStorageControl::should_post_buffer_full_message() const {
--- a/src/hotspot/share/opto/compile.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/opto/compile.cpp	Wed May 23 09:33:37 2018 -0700
@@ -2422,6 +2422,8 @@
     return;
   }
 
+  print_method(PHASE_MATCHING, 2);
+
   // Build a proper-looking CFG
   PhaseCFG cfg(node_arena(), root(), matcher);
   _cfg = &cfg;
--- a/src/hotspot/share/opto/gcm.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/opto/gcm.cpp	Wed May 23 09:33:37 2018 -0700
@@ -684,49 +684,51 @@
     assert(store_block != NULL, "unused killing projections skipped above");
 
     if (store->is_Phi()) {
-      // 'load' uses memory which is one (or more) of the Phi's inputs.
-      // It must be scheduled not before the Phi, but rather before
-      // each of the relevant Phi inputs.
-      //
-      // Instead of finding the LCA of all inputs to a Phi that match 'mem',
-      // we mark each corresponding predecessor block and do a combined
-      // hoisting operation later (raise_LCA_above_marks).
-      //
-      // Do not assert(store_block != early, "Phi merging memory after access")
-      // PhiNode may be at start of block 'early' with backedge to 'early'
-      DEBUG_ONLY(bool found_match = false);
-      for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
-        if (store->in(j) == mem) {   // Found matching input?
-          DEBUG_ONLY(found_match = true);
-          Block* pred_block = get_block_for_node(store_block->pred(j));
-          if (pred_block != early) {
-            // If any predecessor of the Phi matches the load's "early block",
-            // we do not need a precedence edge between the Phi and 'load'
-            // since the load will be forced into a block preceding the Phi.
-            pred_block->set_raise_LCA_mark(load_index);
-            assert(!LCA_orig->dominates(pred_block) ||
-                   early->dominates(pred_block), "early is high enough");
-            must_raise_LCA = true;
-          } else {
-            // anti-dependent upon PHI pinned below 'early', no edge needed
-            LCA = early;             // but can not schedule below 'early'
+      if (store->in(0)->is_Loop()) {
+        // 'load' uses memory which is one (or more) of the Phi's inputs.
+        // It must be scheduled not before the Phi, but rather before
+        // each of the relevant Phi inputs.
+        //
+        // Instead of finding the LCA of all inputs to a Phi that match 'mem',
+        // we mark each corresponding predecessor block and do a combined
+        // hoisting operation later (raise_LCA_above_marks).
+        //
+        // Do not assert(store_block != early, "Phi merging memory after access")
+        // PhiNode may be at start of block 'early' with backedge to 'early'
+        DEBUG_ONLY(bool found_match = false);
+        for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
+          if (store->in(j) == mem) {   // Found matching input?
+            DEBUG_ONLY(found_match = true);
+            Block* pred_block = get_block_for_node(store_block->pred(j));
+            if (pred_block != early) {
+              // If any predecessor of the Phi matches the load's "early block",
+              // we do not need a precedence edge between the Phi and 'load'
+              // since the load will be forced into a block preceding the Phi.
+              pred_block->set_raise_LCA_mark(load_index);
+              assert(!LCA_orig->dominates(pred_block) ||
+                     early->dominates(pred_block), "early is high enough");
+              must_raise_LCA = true;
+            } else {
+              // anti-dependent upon PHI pinned below 'early', no edge needed
+              LCA = early;             // but can not schedule below 'early'
+            }
           }
         }
-      }
-      assert(found_match, "no worklist bug");
+        assert(found_match, "no worklist bug");
 #ifdef TRACK_PHI_INPUTS
 #ifdef ASSERT
-      // This assert asks about correct handling of PhiNodes, which may not
-      // have all input edges directly from 'mem'. See BugId 4621264
-      int num_mem_inputs = phi_inputs.at_grow(store->_idx,0) + 1;
-      // Increment by exactly one even if there are multiple copies of 'mem'
-      // coming into the phi, because we will run this block several times
-      // if there are several copies of 'mem'.  (That's how DU iterators work.)
-      phi_inputs.at_put(store->_idx, num_mem_inputs);
-      assert(PhiNode::Input + num_mem_inputs < store->req(),
-             "Expect at least one phi input will not be from original memory state");
+        // This assert asks about correct handling of PhiNodes, which may not
+        // have all input edges directly from 'mem'. See BugId 4621264
+        int num_mem_inputs = phi_inputs.at_grow(store->_idx,0) + 1;
+        // Increment by exactly one even if there are multiple copies of 'mem'
+        // coming into the phi, because we will run this block several times
+        // if there are several copies of 'mem'.  (That's how DU iterators work.)
+        phi_inputs.at_put(store->_idx, num_mem_inputs);
+        assert(PhiNode::Input + num_mem_inputs < store->req(),
+               "Expect at least one phi input will not be from original memory state");
 #endif //ASSERT
 #endif //TRACK_PHI_INPUTS
+      }
     } else if (store_block != early) {
       // 'store' is between the current LCA and earliest possible block.
       // Label its block, and decide later on how to raise the LCA
--- a/src/hotspot/share/opto/phasetype.hpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/opto/phasetype.hpp	Wed May 23 09:33:37 2018 -0700
@@ -49,6 +49,7 @@
   PHASE_BEFORE_BEAUTIFY_LOOPS,
   PHASE_AFTER_BEAUTIFY_LOOPS,
   PHASE_BEFORE_MATCHING,
+  PHASE_MATCHING,
   PHASE_INCREMENTAL_INLINE,
   PHASE_INCREMENTAL_BOXING_INLINE,
   PHASE_END,
@@ -83,7 +84,8 @@
       case PHASE_AFTER_CLOOPS:               return "After CountedLoop";
       case PHASE_BEFORE_BEAUTIFY_LOOPS:      return "Before beautify loops";
       case PHASE_AFTER_BEAUTIFY_LOOPS:       return "After beautify loops";
-      case PHASE_BEFORE_MATCHING:            return "Before Matching";
+      case PHASE_BEFORE_MATCHING:            return "Before matching";
+      case PHASE_MATCHING:                   return "After matching";
       case PHASE_INCREMENTAL_INLINE:         return "Incremental Inline";
       case PHASE_INCREMENTAL_BOXING_INLINE:  return "Incremental Boxing Inline";
       case PHASE_END:                        return "End";
--- a/src/hotspot/share/runtime/semaphore.hpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/runtime/semaphore.hpp	Wed May 23 09:33:37 2018 -0700
@@ -57,7 +57,6 @@
 
   bool trywait()              { return _impl.trywait(); }
 
-  void wait_with_safepoint_check();
   void wait_with_safepoint_check(JavaThread* thread);
 };
 
--- a/src/hotspot/share/runtime/semaphore.inline.hpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/runtime/semaphore.inline.hpp	Wed May 23 09:33:37 2018 -0700
@@ -38,14 +38,4 @@
   _impl.wait();
 }
 
-inline void Semaphore::wait_with_safepoint_check() {
-  Thread* thread = Thread::current();
-  if (thread->is_Java_thread()) {
-    wait_with_safepoint_check(static_cast<JavaThread*>(thread));
-  } else {
-    // Wait for value
-    _impl.wait();
-  }
-}
-
 #endif // SHARE_VM_RUNTIME_SEMAPHORE_INLINE_HPP
--- a/src/hotspot/share/utilities/hashtable.cpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/utilities/hashtable.cpp	Wed May 23 09:33:37 2018 -0700
@@ -320,7 +320,8 @@
 // literals.
 
 template <class T, MEMFLAGS F> void Hashtable<T, F>::print_table_statistics(outputStream* st,
-                                                                            const char *table_name) {
+                                                                            const char *table_name,
+                                                                            T (*literal_load_barrier)(HashtableEntry<T, F>*)) {
   NumberSeq summary;
   int literal_bytes = 0;
   for (int i = 0; i < this->table_size(); ++i) {
@@ -328,7 +329,8 @@
     for (HashtableEntry<T, F>* e = this->bucket(i);
          e != NULL; e = e->next()) {
       count++;
-      literal_bytes += literal_size(e->literal());
+      T l = (literal_load_barrier != NULL) ? literal_load_barrier(e) : e->literal();
+      literal_bytes += literal_size(l);
     }
     summary.add((double)count);
   }
--- a/src/hotspot/share/utilities/hashtable.hpp	Wed May 23 17:02:13 2018 +0800
+++ b/src/hotspot/share/utilities/hashtable.hpp	Wed May 23 09:33:37 2018 -0700
@@ -265,7 +265,7 @@
     return this->hash_to_index(compute_hash(name));
   }
 
-  void print_table_statistics(outputStream* st, const char *table_name);
+  void print_table_statistics(outputStream* st, const char *table_name, T (*literal_load_barrier)(HashtableEntry<T, F>*) = NULL);
 
  protected:
 
--- a/src/java.base/share/classes/java/lang/String.java	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.base/share/classes/java/lang/String.java	Wed May 23 09:33:37 2018 -0700
@@ -2180,14 +2180,23 @@
      *
      * <p> The {@code limit} parameter controls the number of times the
      * pattern is applied and therefore affects the length of the resulting
-     * array.  If the limit <i>n</i> is greater than zero then the pattern
-     * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
-     * length will be no greater than <i>n</i>, and the array's last entry
-     * will contain all input beyond the last matched delimiter.  If <i>n</i>
-     * is non-positive then the pattern will be applied as many times as
-     * possible and the array can have any length.  If <i>n</i> is zero then
-     * the pattern will be applied as many times as possible, the array can
-     * have any length, and trailing empty strings will be discarded.
+     * array.
+     * <ul>
+     *    <li><p>
+     *    If the <i>limit</i> is positive then the pattern will be applied
+     *    at most <i>limit</i>&nbsp;-&nbsp;1 times, the array's length will be
+     *    no greater than <i>limit</i>, and the array's last entry will contain
+     *    all input beyond the last matched delimiter.</p></li>
+     *
+     *    <li><p>
+     *    If the <i>limit</i> is zero then the pattern will be applied as
+     *    many times as possible, the array can have any length, and trailing
+     *    empty strings will be discarded.</p></li>
+     *
+     *    <li><p>
+     *    If the <i>limit</i> is negative then the pattern will be applied
+     *    as many times as possible and the array can have any length.</p></li>
+     * </ul>
      *
      * <p> The string {@code "boo:and:foo"}, for example, yields the
      * following results with these parameters:
--- a/src/java.base/share/classes/java/util/ArrayList.java	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.base/share/classes/java/util/ArrayList.java	Wed May 23 09:33:37 2018 -0700
@@ -1221,6 +1221,10 @@
             return true;
         }
 
+        public void replaceAll(UnaryOperator<E> operator) {
+            root.replaceAllRange(operator, offset, offset + size);
+        }
+
         public boolean removeAll(Collection<?> c) {
             return batchRemove(c, false);
         }
@@ -1724,15 +1728,18 @@
 
     @Override
     public void replaceAll(UnaryOperator<E> operator) {
+        replaceAllRange(operator, 0, size);
+        modCount++;
+    }
+
+    private void replaceAllRange(UnaryOperator<E> operator, int i, int end) {
         Objects.requireNonNull(operator);
         final int expectedModCount = modCount;
         final Object[] es = elementData;
-        final int size = this.size;
-        for (int i = 0; modCount == expectedModCount && i < size; i++)
+        for (; modCount == expectedModCount && i < end; i++)
             es[i] = operator.apply(elementAt(es, i));
         if (modCount != expectedModCount)
             throw new ConcurrentModificationException();
-        modCount++;
     }
 
     @Override
--- a/src/java.base/share/classes/java/util/PriorityQueue.java	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java	Wed May 23 09:33:37 2018 -0700
@@ -26,6 +26,7 @@
 package java.util;
 
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 import jdk.internal.misc.SharedSecrets;
 
 /**
@@ -81,6 +82,7 @@
  * @author Josh Bloch, Doug Lea
  * @param <E> the type of elements held in this queue
  */
+@SuppressWarnings("unchecked")
 public class PriorityQueue<E> extends AbstractQueue<E>
     implements java.io.Serializable {
 
@@ -187,7 +189,6 @@
      * @throws NullPointerException if the specified collection or any
      *         of its elements are null
      */
-    @SuppressWarnings("unchecked")
     public PriorityQueue(Collection<? extends E> c) {
         if (c instanceof SortedSet<?>) {
             SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
@@ -219,7 +220,6 @@
      * @throws NullPointerException if the specified priority queue or any
      *         of its elements are null
      */
-    @SuppressWarnings("unchecked")
     public PriorityQueue(PriorityQueue<? extends E> c) {
         this.comparator = (Comparator<? super E>) c.comparator();
         initFromPriorityQueue(c);
@@ -238,15 +238,19 @@
      * @throws NullPointerException if the specified sorted set or any
      *         of its elements are null
      */
-    @SuppressWarnings("unchecked")
     public PriorityQueue(SortedSet<? extends E> c) {
         this.comparator = (Comparator<? super E>) c.comparator();
         initElementsFromCollection(c);
     }
 
+    /** Ensures that queue[0] exists, helping peek() and poll(). */
+    private static Object[] ensureNonEmpty(Object[] es) {
+        return (es.length > 0) ? es : new Object[1];
+    }
+
     private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
         if (c.getClass() == PriorityQueue.class) {
-            this.queue = c.toArray();
+            this.queue = ensureNonEmpty(c.toArray());
             this.size = c.size();
         } else {
             initFromCollection(c);
@@ -254,17 +258,17 @@
     }
 
     private void initElementsFromCollection(Collection<? extends E> c) {
-        Object[] a = c.toArray();
+        Object[] es = c.toArray();
+        int len = es.length;
         // If c.toArray incorrectly doesn't return Object[], copy it.
-        if (a.getClass() != Object[].class)
-            a = Arrays.copyOf(a, a.length, Object[].class);
-        int len = a.length;
+        if (es.getClass() != Object[].class)
+            es = Arrays.copyOf(es, len, Object[].class);
         if (len == 1 || this.comparator != null)
-            for (Object e : a)
+            for (Object e : es)
                 if (e == null)
                     throw new NullPointerException();
-        this.queue = a;
-        this.size = a.length;
+        this.queue = ensureNonEmpty(es);
+        this.size = len;
     }
 
     /**
@@ -344,15 +348,15 @@
         return true;
     }
 
-    @SuppressWarnings("unchecked")
     public E peek() {
-        return (size == 0) ? null : (E) queue[0];
+        return (E) queue[0];
     }
 
     private int indexOf(Object o) {
         if (o != null) {
-            for (int i = 0; i < size; i++)
-                if (o.equals(queue[i]))
+            final Object[] es = queue;
+            for (int i = 0, n = size; i < n; i++)
+                if (o.equals(es[i]))
                     return i;
         }
         return -1;
@@ -380,20 +384,18 @@
     }
 
     /**
-     * Version of remove using reference equality, not equals.
-     * Needed by iterator.remove.
+     * Identity-based version for use in Itr.remove.
      *
      * @param o element to be removed from this queue, if present
-     * @return {@code true} if removed
      */
-    boolean removeEq(Object o) {
-        for (int i = 0; i < size; i++) {
-            if (o == queue[i]) {
+    void removeEq(Object o) {
+        final Object[] es = queue;
+        for (int i = 0, n = size; i < n; i++) {
+            if (o == es[i]) {
                 removeAt(i);
-                return true;
+                break;
             }
         }
-        return false;
     }
 
     /**
@@ -461,7 +463,6 @@
      *         this queue
      * @throws NullPointerException if the specified array is null
      */
-    @SuppressWarnings("unchecked")
     public <T> T[] toArray(T[] a) {
         final int size = this.size;
         if (a.length < size)
@@ -530,7 +531,6 @@
                 (forgetMeNot != null && !forgetMeNot.isEmpty());
         }
 
-        @SuppressWarnings("unchecked")
         public E next() {
             if (expectedModCount != modCount)
                 throw new ConcurrentModificationException();
@@ -578,22 +578,29 @@
      */
     public void clear() {
         modCount++;
-        for (int i = 0; i < size; i++)
-            queue[i] = null;
+        final Object[] es = queue;
+        for (int i = 0, n = size; i < n; i++)
+            es[i] = null;
         size = 0;
     }
 
-    @SuppressWarnings("unchecked")
     public E poll() {
-        if (size == 0)
-            return null;
-        int s = --size;
-        modCount++;
-        E result = (E) queue[0];
-        E x = (E) queue[s];
-        queue[s] = null;
-        if (s != 0)
-            siftDown(0, x);
+        final Object[] es;
+        final E result;
+
+        if ((result = (E) ((es = queue)[0])) != null) {
+            modCount++;
+            final int n;
+            final E x = (E) es[(n = --size)];
+            es[n] = null;
+            if (n > 0) {
+                final Comparator<? super E> cmp;
+                if ((cmp = comparator) == null)
+                    siftDownComparable(0, x, es, n);
+                else
+                    siftDownUsingComparator(0, x, es, n, cmp);
+            }
+        }
         return result;
     }
 
@@ -609,20 +616,20 @@
      * position before i. This fact is used by iterator.remove so as to
      * avoid missing traversing elements.
      */
-    @SuppressWarnings("unchecked")
     E removeAt(int i) {
         // assert i >= 0 && i < size;
+        final Object[] es = queue;
         modCount++;
         int s = --size;
         if (s == i) // removed last element
-            queue[i] = null;
+            es[i] = null;
         else {
-            E moved = (E) queue[s];
-            queue[s] = null;
+            E moved = (E) es[s];
+            es[s] = null;
             siftDown(i, moved);
-            if (queue[i] == moved) {
+            if (es[i] == moved) {
                 siftUp(i, moved);
-                if (queue[i] != moved)
+                if (es[i] != moved)
                     return moved;
             }
         }
@@ -643,36 +650,35 @@
      */
     private void siftUp(int k, E x) {
         if (comparator != null)
-            siftUpUsingComparator(k, x);
+            siftUpUsingComparator(k, x, queue, comparator);
         else
-            siftUpComparable(k, x);
+            siftUpComparable(k, x, queue);
     }
 
-    @SuppressWarnings("unchecked")
-    private void siftUpComparable(int k, E x) {
-        Comparable<? super E> key = (Comparable<? super E>) x;
+    private static <T> void siftUpComparable(int k, T x, Object[] es) {
+        Comparable<? super T> key = (Comparable<? super T>) x;
         while (k > 0) {
             int parent = (k - 1) >>> 1;
-            Object e = queue[parent];
-            if (key.compareTo((E) e) >= 0)
+            Object e = es[parent];
+            if (key.compareTo((T) e) >= 0)
                 break;
-            queue[k] = e;
+            es[k] = e;
             k = parent;
         }
-        queue[k] = key;
+        es[k] = key;
     }
 
-    @SuppressWarnings("unchecked")
-    private void siftUpUsingComparator(int k, E x) {
+    private static <T> void siftUpUsingComparator(
+        int k, T x, Object[] es, Comparator<? super T> cmp) {
         while (k > 0) {
             int parent = (k - 1) >>> 1;
-            Object e = queue[parent];
-            if (comparator.compare(x, (E) e) >= 0)
+            Object e = es[parent];
+            if (cmp.compare(x, (T) e) >= 0)
                 break;
-            queue[k] = e;
+            es[k] = e;
             k = parent;
         }
-        queue[k] = x;
+        es[k] = x;
     }
 
     /**
@@ -685,46 +691,46 @@
      */
     private void siftDown(int k, E x) {
         if (comparator != null)
-            siftDownUsingComparator(k, x);
+            siftDownUsingComparator(k, x, queue, size, comparator);
         else
-            siftDownComparable(k, x);
+            siftDownComparable(k, x, queue, size);
     }
 
-    @SuppressWarnings("unchecked")
-    private void siftDownComparable(int k, E x) {
-        Comparable<? super E> key = (Comparable<? super E>)x;
-        int half = size >>> 1;        // loop while a non-leaf
+    private static <T> void siftDownComparable(int k, T x, Object[] es, int n) {
+        // assert n > 0;
+        Comparable<? super T> key = (Comparable<? super T>)x;
+        int half = n >>> 1;           // loop while a non-leaf
         while (k < half) {
             int child = (k << 1) + 1; // assume left child is least
-            Object c = queue[child];
+            Object c = es[child];
             int right = child + 1;
-            if (right < size &&
-                ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
-                c = queue[child = right];
-            if (key.compareTo((E) c) <= 0)
+            if (right < n &&
+                ((Comparable<? super T>) c).compareTo((T) es[right]) > 0)
+                c = es[child = right];
+            if (key.compareTo((T) c) <= 0)
                 break;
-            queue[k] = c;
+            es[k] = c;
             k = child;
         }
-        queue[k] = key;
+        es[k] = key;
     }
 
-    @SuppressWarnings("unchecked")
-    private void siftDownUsingComparator(int k, E x) {
-        int half = size >>> 1;
+    private static <T> void siftDownUsingComparator(
+        int k, T x, Object[] es, int n, Comparator<? super T> cmp) {
+        // assert n > 0;
+        int half = n >>> 1;
         while (k < half) {
             int child = (k << 1) + 1;
-            Object c = queue[child];
+            Object c = es[child];
             int right = child + 1;
-            if (right < size &&
-                comparator.compare((E) c, (E) queue[right]) > 0)
-                c = queue[child = right];
-            if (comparator.compare(x, (E) c) <= 0)
+            if (right < n && cmp.compare((T) c, (T) es[right]) > 0)
+                c = es[child = right];
+            if (cmp.compare(x, (T) c) <= 0)
                 break;
-            queue[k] = c;
+            es[k] = c;
             k = child;
         }
-        queue[k] = x;
+        es[k] = x;
     }
 
     /**
@@ -732,16 +738,16 @@
      * assuming nothing about the order of the elements prior to the call.
      * This classic algorithm due to Floyd (1964) is known to be O(size).
      */
-    @SuppressWarnings("unchecked")
     private void heapify() {
         final Object[] es = queue;
-        int i = (size >>> 1) - 1;
-        if (comparator == null)
+        int n = size, i = (n >>> 1) - 1;
+        final Comparator<? super E> cmp;
+        if ((cmp = comparator) == null)
             for (; i >= 0; i--)
-                siftDownComparable(i, (E) es[i]);
+                siftDownComparable(i, (E) es[i], es, n);
         else
             for (; i >= 0; i--)
-                siftDownUsingComparator(i, (E) es[i]);
+                siftDownUsingComparator(i, (E) es[i], es, n, cmp);
     }
 
     /**
@@ -775,8 +781,9 @@
         s.writeInt(Math.max(2, size + 1));
 
         // Write out all elements in the "proper order".
-        for (int i = 0; i < size; i++)
-            s.writeObject(queue[i]);
+        final Object[] es = queue;
+        for (int i = 0, n = size; i < n; i++)
+            s.writeObject(es[i]);
     }
 
     /**
@@ -797,11 +804,11 @@
         s.readInt();
 
         SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, size);
-        queue = new Object[size];
+        final Object[] es = queue = new Object[Math.max(size, 1)];
 
         // Read in all elements.
-        for (int i = 0; i < size; i++)
-            queue[i] = s.readObject();
+        for (int i = 0, n = size; i < n; i++)
+            es[i] = s.readObject();
 
         // Elements are guaranteed to be in "proper order", but the
         // spec has never explained what that might be.
@@ -853,15 +860,14 @@
                 new PriorityQueueSpliterator(lo, index = mid, expectedModCount);
         }
 
-        @SuppressWarnings("unchecked")
         public void forEachRemaining(Consumer<? super E> action) {
             if (action == null)
                 throw new NullPointerException();
             if (fence < 0) { fence = size; expectedModCount = modCount; }
-            final Object[] a = queue;
+            final Object[] es = queue;
             int i, hi; E e;
             for (i = index, index = hi = fence; i < hi; i++) {
-                if ((e = (E) a[i]) == null)
+                if ((e = (E) es[i]) == null)
                     break;      // must be CME
                 action.accept(e);
             }
@@ -869,7 +875,6 @@
                 throw new ConcurrentModificationException();
         }
 
-        @SuppressWarnings("unchecked")
         public boolean tryAdvance(Consumer<? super E> action) {
             if (action == null)
                 throw new NullPointerException();
@@ -895,4 +900,88 @@
             return Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.NONNULL;
         }
     }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    // A tiny bit set implementation
+
+    private static long[] nBits(int n) {
+        return new long[((n - 1) >> 6) + 1];
+    }
+    private static void setBit(long[] bits, int i) {
+        bits[i >> 6] |= 1L << i;
+    }
+    private static boolean isClear(long[] bits, int i) {
+        return (bits[i >> 6] & (1L << i)) == 0;
+    }
+
+    /** Implementation of bulk remove methods. */
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        final int expectedModCount = ++modCount;
+        final Object[] es = queue;
+        final int end = size;
+        int i;
+        // Optimize for initial run of survivors
+        for (i = 0; i < end && !filter.test((E) es[i]); i++)
+            ;
+        if (i >= end) {
+            if (modCount != expectedModCount)
+                throw new ConcurrentModificationException();
+            return false;
+        }
+        // Tolerate predicates that reentrantly access the collection for
+        // read (but writers still get CME), so traverse once to find
+        // elements to delete, a second pass to physically expunge.
+        final int beg = i;
+        final long[] deathRow = nBits(end - beg);
+        deathRow[0] = 1L;   // set bit 0
+        for (i = beg + 1; i < end; i++)
+            if (filter.test((E) es[i]))
+                setBit(deathRow, i - beg);
+        if (modCount != expectedModCount)
+            throw new ConcurrentModificationException();
+        int w = beg;
+        for (i = beg; i < end; i++)
+            if (isClear(deathRow, i - beg))
+                es[w++] = es[i];
+        for (i = size = w; i < end; i++)
+            es[i] = null;
+        heapify();
+        return true;
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final int expectedModCount = modCount;
+        final Object[] es = queue;
+        for (int i = 0, n = size; i < n; i++)
+            action.accept((E) es[i]);
+        if (expectedModCount != modCount)
+            throw new ConcurrentModificationException();
+    }
 }
--- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java	Wed May 23 09:33:37 2018 -0700
@@ -51,6 +51,7 @@
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Consumer;
+import java.util.function.Predicate;
 import jdk.internal.misc.SharedSecrets;
 
 /**
@@ -167,12 +168,12 @@
     /**
      * Lock used for all public operations.
      */
-    private final ReentrantLock lock;
+    private final ReentrantLock lock = new ReentrantLock();
 
     /**
      * Condition for blocking when empty.
      */
-    private final Condition notEmpty;
+    private final Condition notEmpty = lock.newCondition();
 
     /**
      * Spinlock for allocation, acquired via CAS.
@@ -224,10 +225,8 @@
                                  Comparator<? super E> comparator) {
         if (initialCapacity < 1)
             throw new IllegalArgumentException();
-        this.lock = new ReentrantLock();
-        this.notEmpty = lock.newCondition();
         this.comparator = comparator;
-        this.queue = new Object[initialCapacity];
+        this.queue = new Object[Math.max(1, initialCapacity)];
     }
 
     /**
@@ -247,8 +246,6 @@
      *         of its elements are null
      */
     public PriorityBlockingQueue(Collection<? extends E> c) {
-        this.lock = new ReentrantLock();
-        this.notEmpty = lock.newCondition();
         boolean heapify = true; // true if not known to be in heap order
         boolean screen = true;  // true if must screen for nulls
         if (c instanceof SortedSet<?>) {
@@ -264,22 +261,27 @@
             if (pq.getClass() == PriorityBlockingQueue.class) // exact match
                 heapify = false;
         }
-        Object[] a = c.toArray();
-        int n = a.length;
+        Object[] es = c.toArray();
+        int n = es.length;
         // If c.toArray incorrectly doesn't return Object[], copy it.
-        if (a.getClass() != Object[].class)
-            a = Arrays.copyOf(a, n, Object[].class);
+        if (es.getClass() != Object[].class)
+            es = Arrays.copyOf(es, n, Object[].class);
         if (screen && (n == 1 || this.comparator != null)) {
-            for (Object elt : a)
-                if (elt == null)
+            for (Object e : es)
+                if (e == null)
                     throw new NullPointerException();
         }
-        this.queue = a;
+        this.queue = ensureNonEmpty(es);
         this.size = n;
         if (heapify)
             heapify();
     }
 
+    /** Ensures that queue[0] exists, helping peek() and poll(). */
+    private static Object[] ensureNonEmpty(Object[] es) {
+        return (es.length > 0) ? es : new Object[1];
+    }
+
     /**
      * Tries to grow array to accommodate at least one more element
      * (but normally expand by about 50%), giving up (allowing retry)
@@ -323,22 +325,23 @@
      * Mechanics for poll().  Call only while holding lock.
      */
     private E dequeue() {
-        int n = size - 1;
-        if (n < 0)
-            return null;
-        else {
-            Object[] array = queue;
-            E result = (E) array[0];
-            E x = (E) array[n];
-            array[n] = null;
-            Comparator<? super E> cmp = comparator;
-            if (cmp == null)
-                siftDownComparable(0, x, array, n);
-            else
-                siftDownUsingComparator(0, x, array, n, cmp);
-            size = n;
-            return result;
+        // assert lock.isHeldByCurrentThread();
+        final Object[] es;
+        final E result;
+
+        if ((result = (E) ((es = queue)[0])) != null) {
+            final int n;
+            final E x = (E) es[(n = --size)];
+            es[n] = null;
+            if (n > 0) {
+                final Comparator<? super E> cmp;
+                if ((cmp = comparator) == null)
+                    siftDownComparable(0, x, es, n);
+                else
+                    siftDownUsingComparator(0, x, es, n, cmp);
+            }
         }
+        return result;
     }
 
     /**
@@ -352,32 +355,32 @@
      *
      * @param k the position to fill
      * @param x the item to insert
-     * @param array the heap array
+     * @param es the heap array
      */
-    private static <T> void siftUpComparable(int k, T x, Object[] array) {
+    private static <T> void siftUpComparable(int k, T x, Object[] es) {
         Comparable<? super T> key = (Comparable<? super T>) x;
         while (k > 0) {
             int parent = (k - 1) >>> 1;
-            Object e = array[parent];
+            Object e = es[parent];
             if (key.compareTo((T) e) >= 0)
                 break;
-            array[k] = e;
+            es[k] = e;
             k = parent;
         }
-        array[k] = key;
+        es[k] = key;
     }
 
-    private static <T> void siftUpUsingComparator(int k, T x, Object[] array,
-                                       Comparator<? super T> cmp) {
+    private static <T> void siftUpUsingComparator(
+        int k, T x, Object[] es, Comparator<? super T> cmp) {
         while (k > 0) {
             int parent = (k - 1) >>> 1;
-            Object e = array[parent];
+            Object e = es[parent];
             if (cmp.compare(x, (T) e) >= 0)
                 break;
-            array[k] = e;
+            es[k] = e;
             k = parent;
         }
-        array[k] = x;
+        es[k] = x;
     }
 
     /**
@@ -387,48 +390,44 @@
      *
      * @param k the position to fill
      * @param x the item to insert
-     * @param array the heap array
+     * @param es the heap array
      * @param n heap size
      */
-    private static <T> void siftDownComparable(int k, T x, Object[] array,
-                                               int n) {
-        if (n > 0) {
-            Comparable<? super T> key = (Comparable<? super T>)x;
-            int half = n >>> 1;           // loop while a non-leaf
-            while (k < half) {
-                int child = (k << 1) + 1; // assume left child is least
-                Object c = array[child];
-                int right = child + 1;
-                if (right < n &&
-                    ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
-                    c = array[child = right];
-                if (key.compareTo((T) c) <= 0)
-                    break;
-                array[k] = c;
-                k = child;
-            }
-            array[k] = key;
+    private static <T> void siftDownComparable(int k, T x, Object[] es, int n) {
+        // assert n > 0;
+        Comparable<? super T> key = (Comparable<? super T>)x;
+        int half = n >>> 1;           // loop while a non-leaf
+        while (k < half) {
+            int child = (k << 1) + 1; // assume left child is least
+            Object c = es[child];
+            int right = child + 1;
+            if (right < n &&
+                ((Comparable<? super T>) c).compareTo((T) es[right]) > 0)
+                c = es[child = right];
+            if (key.compareTo((T) c) <= 0)
+                break;
+            es[k] = c;
+            k = child;
         }
+        es[k] = key;
     }
 
-    private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
-                                                    int n,
-                                                    Comparator<? super T> cmp) {
-        if (n > 0) {
-            int half = n >>> 1;
-            while (k < half) {
-                int child = (k << 1) + 1;
-                Object c = array[child];
-                int right = child + 1;
-                if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
-                    c = array[child = right];
-                if (cmp.compare(x, (T) c) <= 0)
-                    break;
-                array[k] = c;
-                k = child;
-            }
-            array[k] = x;
+    private static <T> void siftDownUsingComparator(
+        int k, T x, Object[] es, int n, Comparator<? super T> cmp) {
+        // assert n > 0;
+        int half = n >>> 1;
+        while (k < half) {
+            int child = (k << 1) + 1;
+            Object c = es[child];
+            int right = child + 1;
+            if (right < n && cmp.compare((T) c, (T) es[right]) > 0)
+                c = es[child = right];
+            if (cmp.compare(x, (T) c) <= 0)
+                break;
+            es[k] = c;
+            k = child;
         }
+        es[k] = x;
     }
 
     /**
@@ -437,17 +436,15 @@
      * This classic algorithm due to Floyd (1964) is known to be O(size).
      */
     private void heapify() {
-        Object[] array = queue;
+        final Object[] es = queue;
         int n = size, i = (n >>> 1) - 1;
-        Comparator<? super E> cmp = comparator;
-        if (cmp == null) {
+        final Comparator<? super E> cmp;
+        if ((cmp = comparator) == null)
             for (; i >= 0; i--)
-                siftDownComparable(i, (E) array[i], array, n);
-        }
-        else {
+                siftDownComparable(i, (E) es[i], es, n);
+        else
             for (; i >= 0; i--)
-                siftDownUsingComparator(i, (E) array[i], array, n, cmp);
-        }
+                siftDownUsingComparator(i, (E) es[i], es, n, cmp);
     }
 
     /**
@@ -481,15 +478,15 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         int n, cap;
-        Object[] array;
-        while ((n = size) >= (cap = (array = queue).length))
-            tryGrow(array, cap);
+        Object[] es;
+        while ((n = size) >= (cap = (es = queue).length))
+            tryGrow(es, cap);
         try {
-            Comparator<? super E> cmp = comparator;
-            if (cmp == null)
-                siftUpComparable(n, e, array);
+            final Comparator<? super E> cmp;
+            if ((cmp = comparator) == null)
+                siftUpComparable(n, e, es);
             else
-                siftUpUsingComparator(n, e, array, cmp);
+                siftUpUsingComparator(n, e, es, cmp);
             size = n + 1;
             notEmpty.signal();
         } finally {
@@ -572,7 +569,7 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            return (size == 0) ? null : (E) queue[0];
+            return (E) queue[0];
         } finally {
             lock.unlock();
         }
@@ -612,10 +609,9 @@
 
     private int indexOf(Object o) {
         if (o != null) {
-            Object[] array = queue;
-            int n = size;
-            for (int i = 0; i < n; i++)
-                if (o.equals(array[i]))
+            final Object[] es = queue;
+            for (int i = 0, n = size; i < n; i++)
+                if (o.equals(es[i]))
                     return i;
         }
         return -1;
@@ -625,23 +621,23 @@
      * Removes the ith element from queue.
      */
     private void removeAt(int i) {
-        Object[] array = queue;
-        int n = size - 1;
+        final Object[] es = queue;
+        final int n = size - 1;
         if (n == i) // removed last element
-            array[i] = null;
+            es[i] = null;
         else {
-            E moved = (E) array[n];
-            array[n] = null;
-            Comparator<? super E> cmp = comparator;
-            if (cmp == null)
-                siftDownComparable(i, moved, array, n);
+            E moved = (E) es[n];
+            es[n] = null;
+            final Comparator<? super E> cmp;
+            if ((cmp = comparator) == null)
+                siftDownComparable(i, moved, es, n);
             else
-                siftDownUsingComparator(i, moved, array, n, cmp);
-            if (array[i] == moved) {
+                siftDownUsingComparator(i, moved, es, n, cmp);
+            if (es[i] == moved) {
                 if (cmp == null)
-                    siftUpComparable(i, moved, array);
+                    siftUpComparable(i, moved, es);
                 else
-                    siftUpUsingComparator(i, moved, array, cmp);
+                    siftUpUsingComparator(i, moved, es, cmp);
             }
         }
         size = n;
@@ -674,14 +670,16 @@
 
     /**
      * Identity-based version for use in Itr.remove.
+     *
+     * @param o element to be removed from this queue, if present
      */
-    void removeEQ(Object o) {
+    void removeEq(Object o) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            Object[] array = queue;
+            final Object[] es = queue;
             for (int i = 0, n = size; i < n; i++) {
-                if (o == array[i]) {
+                if (o == es[i]) {
                     removeAt(i);
                     break;
                 }
@@ -757,11 +755,10 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            Object[] array = queue;
-            int n = size;
+            final Object[] es = queue;
+            for (int i = 0, n = size; i < n; i++)
+                es[i] = null;
             size = 0;
-            for (int i = 0; i < n; i++)
-                array[i] = null;
         } finally {
             lock.unlock();
         }
@@ -862,10 +859,9 @@
     final class Itr implements Iterator<E> {
         final Object[] array; // Array of all elements
         int cursor;           // index of next element to return
-        int lastRet;          // index of last element, or -1 if no such
+        int lastRet = -1;     // index of last element, or -1 if no such
 
         Itr(Object[] array) {
-            lastRet = -1;
             this.array = array;
         }
 
@@ -882,9 +878,22 @@
         public void remove() {
             if (lastRet < 0)
                 throw new IllegalStateException();
-            removeEQ(array[lastRet]);
+            removeEq(array[lastRet]);
             lastRet = -1;
         }
+
+        public void forEachRemaining(Consumer<? super E> action) {
+            Objects.requireNonNull(action);
+            final Object[] es = array;
+            int i;
+            if ((i = cursor) < es.length) {
+                lastRet = -1;
+                cursor = es.length;
+                for (; i < es.length; i++)
+                    action.accept((E) es[i]);
+                lastRet = es.length - 1;
+            }
+        }
     }
 
     /**
@@ -924,7 +933,7 @@
             s.defaultReadObject();
             int sz = q.size();
             SharedSecrets.getJavaObjectInputStreamAccess().checkArray(s, Object[].class, sz);
-            this.queue = new Object[sz];
+            this.queue = new Object[Math.max(1, sz)];
             comparator = q.comparator();
             addAll(q);
         } finally {
@@ -963,10 +972,10 @@
         public void forEachRemaining(Consumer<? super E> action) {
             Objects.requireNonNull(action);
             final int hi = getFence(), lo = index;
-            final Object[] a = array;
+            final Object[] es = array;
             index = hi;                 // ensure exhaustion
             for (int i = lo; i < hi; i++)
-                action.accept((E) a[i]);
+                action.accept((E) es[i]);
         }
 
         public boolean tryAdvance(Consumer<? super E> action) {
@@ -1008,6 +1017,93 @@
         return new PBQSpliterator();
     }
 
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeIf(Predicate<? super E> filter) {
+        Objects.requireNonNull(filter);
+        return bulkRemove(filter);
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean removeAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> c.contains(e));
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public boolean retainAll(Collection<?> c) {
+        Objects.requireNonNull(c);
+        return bulkRemove(e -> !c.contains(e));
+    }
+
+    // A tiny bit set implementation
+
+    private static long[] nBits(int n) {
+        return new long[((n - 1) >> 6) + 1];
+    }
+    private static void setBit(long[] bits, int i) {
+        bits[i >> 6] |= 1L << i;
+    }
+    private static boolean isClear(long[] bits, int i) {
+        return (bits[i >> 6] & (1L << i)) == 0;
+    }
+
+    /** Implementation of bulk remove methods. */
+    private boolean bulkRemove(Predicate<? super E> filter) {
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            final Object[] es = queue;
+            final int end = size;
+            int i;
+            // Optimize for initial run of survivors
+            for (i = 0; i < end && !filter.test((E) es[i]); i++)
+                ;
+            if (i >= end)
+                return false;
+            // Tolerate predicates that reentrantly access the
+            // collection for read, so traverse once to find elements
+            // to delete, a second pass to physically expunge.
+            final int beg = i;
+            final long[] deathRow = nBits(end - beg);
+            deathRow[0] = 1L;   // set bit 0
+            for (i = beg + 1; i < end; i++)
+                if (filter.test((E) es[i]))
+                    setBit(deathRow, i - beg);
+            int w = beg;
+            for (i = beg; i < end; i++)
+                if (isClear(deathRow, i - beg))
+                    es[w++] = es[i];
+            for (i = size = w; i < end; i++)
+                es[i] = null;
+            heapify();
+            return true;
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * @throws NullPointerException {@inheritDoc}
+     */
+    public void forEach(Consumer<? super E> action) {
+        Objects.requireNonNull(action);
+        final ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            final Object[] es = queue;
+            for (int i = 0, n = size; i < n; i++)
+                action.accept((E) es[i]);
+        } finally {
+            lock.unlock();
+        }
+    }
+
     // VarHandle mechanics
     private static final VarHandle ALLOCATIONSPINLOCK;
     static {
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Wed May 23 09:33:37 2018 -0700
@@ -1193,14 +1193,23 @@
      *
      * <p> The {@code limit} parameter controls the number of times the
      * pattern is applied and therefore affects the length of the resulting
-     * array.  If the limit <i>n</i> is greater than zero then the pattern
-     * will be applied at most <i>n</i>&nbsp;-&nbsp;1 times, the array's
-     * length will be no greater than <i>n</i>, and the array's last entry
-     * will contain all input beyond the last matched delimiter.  If <i>n</i>
-     * is non-positive then the pattern will be applied as many times as
-     * possible and the array can have any length.  If <i>n</i> is zero then
-     * the pattern will be applied as many times as possible, the array can
-     * have any length, and trailing empty strings will be discarded.
+     * array.
+     * <ul>
+     *    <li><p>
+     *    If the <i>limit</i> is positive then the pattern will be applied
+     *    at most <i>limit</i>&nbsp;-&nbsp;1 times, the array's length will be
+     *    no greater than <i>limit</i>, and the array's last entry will contain
+     *    all input beyond the last matched delimiter.</p></li>
+     *
+     *    <li><p>
+     *    If the <i>limit</i> is zero then the pattern will be applied as
+     *    many times as possible, the array can have any length, and trailing
+     *    empty strings will be discarded.</p></li>
+     *
+     *    <li><p>
+     *    If the <i>limit</i> is negative then the pattern will be applied
+     *    as many times as possible and the array can have any length.</p></li>
+     * </ul>
      *
      * <p> The input {@code "boo:and:foo"}, for example, yields the following
      * results with these parameters:
--- a/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Wed May 23 17:02:13 2018 +0800
+++ b/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Wed May 23 09:33:37 2018 -0700
@@ -83,7 +83,10 @@
 jint useMitShmExt = CANT_USE_MITSHM;
 jint useMitShmPixmaps = CANT_USE_MITSHM;
 jint forceSharedPixmaps = JNI_FALSE;
+
+#ifdef MITSHM
 int mitShmPermissionMask = MITSHM_PERM_OWNER;
+#endif
 
 /* Cached shared image, one for all surface datas. */
 static XImage * cachedXImage;
--- a/test/hotspot/jtreg/compiler/c2/Test6843752.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/hotspot/jtreg/compiler/c2/Test6843752.java	Wed May 23 09:33:37 2018 -0700
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6843752
+ * @bug 6843752 8192992
  * @summary missing code for an anti-dependent Phi in GCM
  *
  * @run main/othervm -Xbatch compiler.c2.Test6843752
--- a/test/jdk/java/lang/Character/Blocks.txt	Wed May 23 17:02:13 2018 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-# Blocks-10.0.0.txt
-# Date: 2017-04-12, 17:30:00 GMT [KW]
-# Copyright (c) 2017 Unicode, Inc.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
-#
-# Unicode Character Database
-# For documentation, see http://www.unicode.org/reports/tr44/
-#
-# Format:
-# Start Code..End Code; Block Name
-
-# ================================================
-
-# Note:   When comparing block names, casing, whitespace, hyphens,
-#         and underbars are ignored.
-#         For example, "Latin Extended-A" and "latin extended a" are equivalent.
-#         For more information on the comparison of property values,
-#            see UAX #44: http://www.unicode.org/reports/tr44/
-#
-#  All block ranges start with a value where (cp MOD 16) = 0,
-#  and end with a value where (cp MOD 16) = 15. In other words,
-#  the last hexadecimal digit of the start of range is ...0
-#  and the last hexadecimal digit of the end of range is ...F.
-#  This constraint on block ranges guarantees that allocations
-#  are done in terms of whole columns, and that code chart display
-#  never involves splitting columns in the charts.
-#
-#  All code points not explicitly listed for Block
-#  have the value No_Block.
-
-# Property:	Block
-#
-# @missing: 0000..10FFFF; No_Block
-
-0000..007F; Basic Latin
-0080..00FF; Latin-1 Supplement
-0100..017F; Latin Extended-A
-0180..024F; Latin Extended-B
-0250..02AF; IPA Extensions
-02B0..02FF; Spacing Modifier Letters
-0300..036F; Combining Diacritical Marks
-0370..03FF; Greek and Coptic
-0400..04FF; Cyrillic
-0500..052F; Cyrillic Supplement
-0530..058F; Armenian
-0590..05FF; Hebrew
-0600..06FF; Arabic
-0700..074F; Syriac
-0750..077F; Arabic Supplement
-0780..07BF; Thaana
-07C0..07FF; NKo
-0800..083F; Samaritan
-0840..085F; Mandaic
-0860..086F; Syriac Supplement
-08A0..08FF; Arabic Extended-A
-0900..097F; Devanagari
-0980..09FF; Bengali
-0A00..0A7F; Gurmukhi
-0A80..0AFF; Gujarati
-0B00..0B7F; Oriya
-0B80..0BFF; Tamil
-0C00..0C7F; Telugu
-0C80..0CFF; Kannada
-0D00..0D7F; Malayalam
-0D80..0DFF; Sinhala
-0E00..0E7F; Thai
-0E80..0EFF; Lao
-0F00..0FFF; Tibetan
-1000..109F; Myanmar
-10A0..10FF; Georgian
-1100..11FF; Hangul Jamo
-1200..137F; Ethiopic
-1380..139F; Ethiopic Supplement
-13A0..13FF; Cherokee
-1400..167F; Unified Canadian Aboriginal Syllabics
-1680..169F; Ogham
-16A0..16FF; Runic
-1700..171F; Tagalog
-1720..173F; Hanunoo
-1740..175F; Buhid
-1760..177F; Tagbanwa
-1780..17FF; Khmer
-1800..18AF; Mongolian
-18B0..18FF; Unified Canadian Aboriginal Syllabics Extended
-1900..194F; Limbu
-1950..197F; Tai Le
-1980..19DF; New Tai Lue
-19E0..19FF; Khmer Symbols
-1A00..1A1F; Buginese
-1A20..1AAF; Tai Tham
-1AB0..1AFF; Combining Diacritical Marks Extended
-1B00..1B7F; Balinese
-1B80..1BBF; Sundanese
-1BC0..1BFF; Batak
-1C00..1C4F; Lepcha
-1C50..1C7F; Ol Chiki
-1C80..1C8F; Cyrillic Extended-C
-1CC0..1CCF; Sundanese Supplement
-1CD0..1CFF; Vedic Extensions
-1D00..1D7F; Phonetic Extensions
-1D80..1DBF; Phonetic Extensions Supplement
-1DC0..1DFF; Combining Diacritical Marks Supplement
-1E00..1EFF; Latin Extended Additional
-1F00..1FFF; Greek Extended
-2000..206F; General Punctuation
-2070..209F; Superscripts and Subscripts
-20A0..20CF; Currency Symbols
-20D0..20FF; Combining Diacritical Marks for Symbols
-2100..214F; Letterlike Symbols
-2150..218F; Number Forms
-2190..21FF; Arrows
-2200..22FF; Mathematical Operators
-2300..23FF; Miscellaneous Technical
-2400..243F; Control Pictures
-2440..245F; Optical Character Recognition
-2460..24FF; Enclosed Alphanumerics
-2500..257F; Box Drawing
-2580..259F; Block Elements
-25A0..25FF; Geometric Shapes
-2600..26FF; Miscellaneous Symbols
-2700..27BF; Dingbats
-27C0..27EF; Miscellaneous Mathematical Symbols-A
-27F0..27FF; Supplemental Arrows-A
-2800..28FF; Braille Patterns
-2900..297F; Supplemental Arrows-B
-2980..29FF; Miscellaneous Mathematical Symbols-B
-2A00..2AFF; Supplemental Mathematical Operators
-2B00..2BFF; Miscellaneous Symbols and Arrows
-2C00..2C5F; Glagolitic
-2C60..2C7F; Latin Extended-C
-2C80..2CFF; Coptic
-2D00..2D2F; Georgian Supplement
-2D30..2D7F; Tifinagh
-2D80..2DDF; Ethiopic Extended
-2DE0..2DFF; Cyrillic Extended-A
-2E00..2E7F; Supplemental Punctuation
-2E80..2EFF; CJK Radicals Supplement
-2F00..2FDF; Kangxi Radicals
-2FF0..2FFF; Ideographic Description Characters
-3000..303F; CJK Symbols and Punctuation
-3040..309F; Hiragana
-30A0..30FF; Katakana
-3100..312F; Bopomofo
-3130..318F; Hangul Compatibility Jamo
-3190..319F; Kanbun
-31A0..31BF; Bopomofo Extended
-31C0..31EF; CJK Strokes
-31F0..31FF; Katakana Phonetic Extensions
-3200..32FF; Enclosed CJK Letters and Months
-3300..33FF; CJK Compatibility
-3400..4DBF; CJK Unified Ideographs Extension A
-4DC0..4DFF; Yijing Hexagram Symbols
-4E00..9FFF; CJK Unified Ideographs
-A000..A48F; Yi Syllables
-A490..A4CF; Yi Radicals
-A4D0..A4FF; Lisu
-A500..A63F; Vai
-A640..A69F; Cyrillic Extended-B
-A6A0..A6FF; Bamum
-A700..A71F; Modifier Tone Letters
-A720..A7FF; Latin Extended-D
-A800..A82F; Syloti Nagri
-A830..A83F; Common Indic Number Forms
-A840..A87F; Phags-pa
-A880..A8DF; Saurashtra
-A8E0..A8FF; Devanagari Extended
-A900..A92F; Kayah Li
-A930..A95F; Rejang
-A960..A97F; Hangul Jamo Extended-A
-A980..A9DF; Javanese
-A9E0..A9FF; Myanmar Extended-B
-AA00..AA5F; Cham
-AA60..AA7F; Myanmar Extended-A
-AA80..AADF; Tai Viet
-AAE0..AAFF; Meetei Mayek Extensions
-AB00..AB2F; Ethiopic Extended-A
-AB30..AB6F; Latin Extended-E
-AB70..ABBF; Cherokee Supplement
-ABC0..ABFF; Meetei Mayek
-AC00..D7AF; Hangul Syllables
-D7B0..D7FF; Hangul Jamo Extended-B
-D800..DB7F; High Surrogates
-DB80..DBFF; High Private Use Surrogates
-DC00..DFFF; Low Surrogates
-E000..F8FF; Private Use Area
-F900..FAFF; CJK Compatibility Ideographs
-FB00..FB4F; Alphabetic Presentation Forms
-FB50..FDFF; Arabic Presentation Forms-A
-FE00..FE0F; Variation Selectors
-FE10..FE1F; Vertical Forms
-FE20..FE2F; Combining Half Marks
-FE30..FE4F; CJK Compatibility Forms
-FE50..FE6F; Small Form Variants
-FE70..FEFF; Arabic Presentation Forms-B
-FF00..FFEF; Halfwidth and Fullwidth Forms
-FFF0..FFFF; Specials
-10000..1007F; Linear B Syllabary
-10080..100FF; Linear B Ideograms
-10100..1013F; Aegean Numbers
-10140..1018F; Ancient Greek Numbers
-10190..101CF; Ancient Symbols
-101D0..101FF; Phaistos Disc
-10280..1029F; Lycian
-102A0..102DF; Carian
-102E0..102FF; Coptic Epact Numbers
-10300..1032F; Old Italic
-10330..1034F; Gothic
-10350..1037F; Old Permic
-10380..1039F; Ugaritic
-103A0..103DF; Old Persian
-10400..1044F; Deseret
-10450..1047F; Shavian
-10480..104AF; Osmanya
-104B0..104FF; Osage
-10500..1052F; Elbasan
-10530..1056F; Caucasian Albanian
-10600..1077F; Linear A
-10800..1083F; Cypriot Syllabary
-10840..1085F; Imperial Aramaic
-10860..1087F; Palmyrene
-10880..108AF; Nabataean
-108E0..108FF; Hatran
-10900..1091F; Phoenician
-10920..1093F; Lydian
-10980..1099F; Meroitic Hieroglyphs
-109A0..109FF; Meroitic Cursive
-10A00..10A5F; Kharoshthi
-10A60..10A7F; Old South Arabian
-10A80..10A9F; Old North Arabian
-10AC0..10AFF; Manichaean
-10B00..10B3F; Avestan
-10B40..10B5F; Inscriptional Parthian
-10B60..10B7F; Inscriptional Pahlavi
-10B80..10BAF; Psalter Pahlavi
-10C00..10C4F; Old Turkic
-10C80..10CFF; Old Hungarian
-10E60..10E7F; Rumi Numeral Symbols
-11000..1107F; Brahmi
-11080..110CF; Kaithi
-110D0..110FF; Sora Sompeng
-11100..1114F; Chakma
-11150..1117F; Mahajani
-11180..111DF; Sharada
-111E0..111FF; Sinhala Archaic Numbers
-11200..1124F; Khojki
-11280..112AF; Multani
-112B0..112FF; Khudawadi
-11300..1137F; Grantha
-11400..1147F; Newa
-11480..114DF; Tirhuta
-11580..115FF; Siddham
-11600..1165F; Modi
-11660..1167F; Mongolian Supplement
-11680..116CF; Takri
-11700..1173F; Ahom
-118A0..118FF; Warang Citi
-11A00..11A4F; Zanabazar Square
-11A50..11AAF; Soyombo
-11AC0..11AFF; Pau Cin Hau
-11C00..11C6F; Bhaiksuki
-11C70..11CBF; Marchen
-11D00..11D5F; Masaram Gondi
-12000..123FF; Cuneiform
-12400..1247F; Cuneiform Numbers and Punctuation
-12480..1254F; Early Dynastic Cuneiform
-13000..1342F; Egyptian Hieroglyphs
-14400..1467F; Anatolian Hieroglyphs
-16800..16A3F; Bamum Supplement
-16A40..16A6F; Mro
-16AD0..16AFF; Bassa Vah
-16B00..16B8F; Pahawh Hmong
-16F00..16F9F; Miao
-16FE0..16FFF; Ideographic Symbols and Punctuation
-17000..187FF; Tangut
-18800..18AFF; Tangut Components
-1B000..1B0FF; Kana Supplement
-1B100..1B12F; Kana Extended-A
-1B170..1B2FF; Nushu
-1BC00..1BC9F; Duployan
-1BCA0..1BCAF; Shorthand Format Controls
-1D000..1D0FF; Byzantine Musical Symbols
-1D100..1D1FF; Musical Symbols
-1D200..1D24F; Ancient Greek Musical Notation
-1D300..1D35F; Tai Xuan Jing Symbols
-1D360..1D37F; Counting Rod Numerals
-1D400..1D7FF; Mathematical Alphanumeric Symbols
-1D800..1DAAF; Sutton SignWriting
-1E000..1E02F; Glagolitic Supplement
-1E800..1E8DF; Mende Kikakui
-1E900..1E95F; Adlam
-1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols
-1F000..1F02F; Mahjong Tiles
-1F030..1F09F; Domino Tiles
-1F0A0..1F0FF; Playing Cards
-1F100..1F1FF; Enclosed Alphanumeric Supplement
-1F200..1F2FF; Enclosed Ideographic Supplement
-1F300..1F5FF; Miscellaneous Symbols and Pictographs
-1F600..1F64F; Emoticons
-1F650..1F67F; Ornamental Dingbats
-1F680..1F6FF; Transport and Map Symbols
-1F700..1F77F; Alchemical Symbols
-1F780..1F7FF; Geometric Shapes Extended
-1F800..1F8FF; Supplemental Arrows-C
-1F900..1F9FF; Supplemental Symbols and Pictographs
-20000..2A6DF; CJK Unified Ideographs Extension B
-2A700..2B73F; CJK Unified Ideographs Extension C
-2B740..2B81F; CJK Unified Ideographs Extension D
-2B820..2CEAF; CJK Unified Ideographs Extension E
-2CEB0..2EBEF; CJK Unified Ideographs Extension F
-2F800..2FA1F; CJK Compatibility Ideographs Supplement
-E0000..E007F; Tags
-E0100..E01EF; Variation Selectors Supplement
-F0000..FFFFF; Supplementary Private Use Area-A
-100000..10FFFF; Supplementary Private Use Area-B
-
-# EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Character/CharPropTest.java	Wed May 23 09:33:37 2018 -0700
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8202771
+ * @summary Check j.l.Character.isDigit/isLetter/isLetterOrDigit/isSpaceChar
+ * /isWhitespace/isTitleCase/isISOControl/isIdentifierIgnorable
+ * /isJavaIdentifierStart/isJavaIdentifierPart/isUnicodeIdentifierStart
+ * /isUnicodeIdentifierPart
+ * @run main CharPropTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
+
+public class CharPropTest {
+    private static int diffs = 0;
+    private static int rangeStart = 0x0000;
+    private static boolean isRange = false;
+
+    public static void main(String[] args) throws Exception {
+        Path path = Paths.get(System.getProperty("test.src", "."),
+                "UnicodeData.txt");
+        try (Stream<String> lines = Files.lines(path)) {
+            lines.map(String::trim)
+                 .filter(line -> line.length() != 0 && line.charAt(0) != '#')
+                 .forEach(line -> handleOneLine(line));
+
+            if (diffs != 0) {
+                throw new RuntimeException("Total differences: " + diffs);
+            }
+        }
+    }
+
+    private static void handleOneLine(String line) {
+        String[] fields = line.split(";");
+        int currentCp = Integer.parseInt(fields[0], 16);
+        String name = fields[1];
+        String category = fields[2];
+
+        // Except single code point, also handle ranges like the following:
+        // 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+        // 4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;
+        if (isRange) {
+            if (name.endsWith("Last>")) {
+                for (int cp = rangeStart; cp <= currentCp; cp++) {
+                    testCodePoint(cp, category);
+                }
+            } else {
+                throw new RuntimeException("Not a valid range, first range <"
+                        + Integer.toHexString(rangeStart) + "> without last.");
+            }
+            isRange = false;
+        } else {
+            if (name.endsWith("First>")) {
+                rangeStart = currentCp;
+                isRange = true;
+            } else {
+                testCodePoint(currentCp, category);
+            }
+        }
+    }
+
+    private static void testCodePoint(int codePoint, String category) {
+        isDigitTest(codePoint, category);
+        isLetterTest(codePoint, category);
+        isLetterOrDigitTest(codePoint, category);
+
+        isSpaceCharTest(codePoint, category);
+        isWhitespaceTest(codePoint, category);
+
+        isTitleCaseTest(codePoint, category);
+
+        isISOControlTest(codePoint);
+
+        isIdentifierIgnorableTest(codePoint, category);
+        isJavaIdentifierStartTest(codePoint, category);
+        isJavaIdentifierPartTest(codePoint, category);
+        isUnicodeIdentifierStartTest(codePoint, category);
+        isUnicodeIdentifierPartTest(codePoint, category);
+    }
+
+    private static void isDigitTest(int codePoint, String category) {
+        boolean actual = Character.isDigit(codePoint);
+        boolean expected = category.equals("Nd");
+        if (actual != expected) {
+            printDiff(codePoint, "isDigit", actual, expected);
+        }
+    }
+
+    private static void isLetterTest(int codePoint, String category) {
+        boolean actual = Character.isLetter(codePoint);
+        boolean expected = isLetter(category);
+        if (actual != expected) {
+            printDiff(codePoint, "isLetter", actual, expected);
+        }
+    }
+
+    private static void isLetterOrDigitTest(int codePoint, String category) {
+        boolean actual = Character.isLetterOrDigit(codePoint);
+        boolean expected = isLetter(category) || category.equals("Nd");
+        if (actual != expected) {
+            printDiff(codePoint, "isLetterOrDigit", actual, expected);
+        }
+    }
+
+    private static void isSpaceCharTest(int codePoint, String category) {
+        boolean actual = Character.isSpaceChar(codePoint);
+        boolean expected = isSpaceChar(category);
+        if (actual != expected) {
+            printDiff(codePoint, "isSpaceChar", actual, expected);
+        }
+    }
+
+    private static void isWhitespaceTest(int codePoint, String category) {
+        boolean actual = Character.isWhitespace(codePoint);
+        boolean expected = isWhitespace(codePoint, category);
+        if (actual != expected) {
+            printDiff(codePoint, "isWhitespace", actual, expected);
+        }
+    }
+
+    private static void isTitleCaseTest(int codePoint, String category) {
+        boolean actual = Character.isTitleCase(codePoint);
+        boolean expected = category.equals("Lt");
+        if (actual != expected) {
+            printDiff(codePoint, "isTitleCase", actual, expected);
+        }
+    }
+
+    private static void isISOControlTest(int codePoint) {
+        boolean actual = Character.isISOControl(codePoint);
+        boolean expected = isISOControl(codePoint);
+        if (actual != expected) {
+            printDiff(codePoint, "isISOControl", actual, expected);
+        }
+    }
+
+    private static void isIdentifierIgnorableTest(int codePoint, String category) {
+        boolean actual = Character.isIdentifierIgnorable(codePoint);
+        boolean expected = isIdentifierIgnorable(codePoint, category);
+        if (actual != expected) {
+            printDiff(codePoint, "isIdentifierIgnorable", actual, expected);
+        }
+    }
+
+    private static void isJavaIdentifierStartTest(int codePoint, String category) {
+        boolean actual = Character.isJavaIdentifierStart(codePoint);
+        boolean expected = isJavaIdentifierStart(category);
+        if (actual != expected) {
+            printDiff(codePoint, "isJavaIdentifierStart", actual, expected);
+        }
+    }
+
+    private static void isJavaIdentifierPartTest(int codePoint, String category) {
+        boolean actual = Character.isJavaIdentifierPart(codePoint);
+        boolean expected = isJavaIdentifierPart(codePoint, category);
+        if (actual != expected) {
+            printDiff(codePoint, "isJavaIdentifierPart", actual, expected);
+        }
+    }
+
+    private static void isUnicodeIdentifierStartTest(int codePoint, String category) {
+        boolean actual = Character.isUnicodeIdentifierStart(codePoint);
+        boolean expected = isUnicodeIdentifierStart(category);
+        if (actual != expected) {
+            printDiff(codePoint, "isUnicodeIdentifierStart", actual, expected);
+        }
+    }
+
+    private static void isUnicodeIdentifierPartTest(int codePoint, String category) {
+        boolean actual = Character.isUnicodeIdentifierPart(codePoint);
+        boolean expected = isUnicodeIdentifierPart(codePoint, category);
+        if (actual != expected) {
+            printDiff(codePoint, "isUnicodeIdentifierPart", actual, expected);
+        }
+    }
+
+    private static boolean isLetter(String category) {
+        return category.equals("Lu") || category.equals("Ll")
+               || category.equals("Lt") || category.equals("Lm")
+               || category.equals("Lo");
+    }
+
+    private static boolean isSpaceChar(String category) {
+        return category.equals("Zs") || category.equals("Zl")
+               || category.equals("Zp");
+    }
+
+    private static boolean isWhitespace(int codePoint, String category) {
+        if (isSpaceChar(category) && codePoint != Integer.parseInt("00A0", 16)
+                && codePoint != Integer.parseInt("2007", 16)
+                && codePoint != Integer.parseInt("202F", 16)) {
+            return true;
+        } else {
+            if (codePoint == Integer.parseInt("0009", 16)
+                    || codePoint == Integer.parseInt("000A", 16)
+                    || codePoint == Integer.parseInt("000B", 16)
+                    || codePoint == Integer.parseInt("000C", 16)
+                    || codePoint == Integer.parseInt("000D", 16)
+                    || codePoint == Integer.parseInt("001C", 16)
+                    || codePoint == Integer.parseInt("001D", 16)
+                    || codePoint == Integer.parseInt("001E", 16)
+                    || codePoint == Integer.parseInt("001F", 16)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isISOControl(int codePoint) {
+        return (codePoint > 0x00 && codePoint < 0x1f)
+               || (codePoint > 0x7f && codePoint < 0x9f)
+               || (codePoint == 0x00 || codePoint == 0x1f || codePoint == 0x7f || codePoint == 0x9f);
+    }
+
+    private static boolean isIdentifierIgnorable(int codePoint, String category) {
+        if (category.equals("Cf")) {
+            return true;
+        } else {
+            int a1 = Integer.parseInt("0000", 16);
+            int a2 = Integer.parseInt("0008", 16);
+            int b1 = Integer.parseInt("000E", 16);
+            int b2 = Integer.parseInt("001B", 16);
+            int c1 = Integer.parseInt("007F", 16);
+            int c2 = Integer.parseInt("009F", 16);
+
+            if ((codePoint > a1 && codePoint < a2) || (codePoint > b1 && codePoint < b2)
+                    || (codePoint > c1 && codePoint < c2) || (codePoint == a1 || codePoint == a2
+                    || codePoint == b1 || codePoint == b2 || codePoint == c1 || codePoint == c2)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean isJavaIdentifierStart(String category) {
+        return isLetter(category) || category.equals("Nl") || category.equals("Sc")
+               || category.equals("Pc");
+    }
+
+    private static boolean isJavaIdentifierPart(int codePoint, String category) {
+        return isLetter(category) || category.equals("Sc") || category.equals("Pc")
+               || category.equals("Nd") || category.equals("Nl")
+               || category.equals("Mc") || category.equals("Mn")
+               || isIdentifierIgnorable(codePoint, category);
+    }
+
+    private static boolean isUnicodeIdentifierStart(String category) {
+        return isLetter(category) || category.equals("Nl");
+    }
+
+    private static boolean isUnicodeIdentifierPart(int codePoint, String category) {
+        return isLetter(category) || category.equals("Pc") || category.equals("Nd")
+               || category.equals("Nl") || category.equals("Mc") || category.equals("Mn")
+               || isIdentifierIgnorable(codePoint, category);
+    }
+
+    private static void printDiff(int codePoint, String method, boolean actual, boolean expected) {
+        System.out.println("Not equal at codePoint <" + Integer.toHexString(codePoint)
+                + ">, method: " + method
+                + ", actual: " + actual + ", expected: " + expected);
+        diffs++;
+    }
+}
--- a/test/jdk/java/lang/Character/CheckBlocks.java	Wed May 23 17:02:13 2018 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,301 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 4830803 4886934 6565620 6959267 7070436 7198195 8032446 8072600
- * @summary  Check that the UnicodeBlock forName() method works as expected and block ranges are correct for all Unicode characters.
- * @run main CheckBlocks
- * @author John O'Conner
- */
-
-import java.io.*;
-import java.util.*;
-import java.lang.Character.UnicodeBlock;
-
-
-public class CheckBlocks {
-
-    static boolean err = false;
-    static Class<?> character;
-
-    public static void main(String[] args) throws Exception {
-        generateBlockList();
-
-        try {
-            character = Class.forName("java.lang.Character$UnicodeBlock");
-        } catch (ClassNotFoundException e) {
-            throw new RuntimeException("Class.forName(\"Character\") failed.");
-        }
-
-        for (Block blk : blocks) {
-            test4830803_1(blk);
-            test4830803_2();
-            test4886934(blk);
-        }
-
-        if (err) {
-            throw new RuntimeException("Failed");
-        } else {
-            System.out.println("Passed");
-        }
-    }
-
-    /**
-     * Check that the UnicodeBlock forName() method works as expected.
-     */
-    private static void test4830803_1(Block blk) throws Exception {
-
-        /*
-         * Try 3 forms of block name in the forName() method. Each form should
-         * produce the same expected block.
-         */
-        String blkName = blk.getName();
-
-        // For backward compatibility
-        if (blkName.equals("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS")) {
-            blkName = "COMBINING_MARKS_FOR_SYMBOLS";
-            System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS is replaced with COMBINING_MARKS_FOR_SYMBOLS for backward compatibility.");
-        } else if (blkName.equals("GREEK_AND_COPTIC")) {
-            blkName = "GREEK";
-            System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK for backward compatibility.");
-        } else if (blkName.equals("CYRILLIC_SUPPLEMENT")) {
-            blkName = "CYRILLIC_SUPPLEMENTARY";
-            System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with CYRILLIC_SUPPLEMENTARY for backward compatibility.");
-        }
-
-        String expectedBlock = null;
-        try {
-            expectedBlock = character.getField(blkName).getName();
-        } catch (NoSuchFieldException | SecurityException e) {
-            System.err.println("Error: " + blkName + " was not found.");
-            err = true;
-            return;
-        }
-
-        String canonicalBlockName = blk.getOriginalName();
-        String idBlockName = expectedBlock;
-        String regexBlockName = toRegExString(canonicalBlockName);
-
-        if (regexBlockName == null) {
-            System.err.println("Error: Block name which was processed with regex was null.");
-            err = true;
-            return;
-        }
-
-        if (!expectedBlock.equals(UnicodeBlock.forName(canonicalBlockName).toString())) {
-            System.err.println("Error #1: UnicodeBlock.forName(\"" +
-                canonicalBlockName + "\") returned wrong value.\n\tGot: " +
-                UnicodeBlock.forName(canonicalBlockName) +
-                "\n\tExpected: " + expectedBlock);
-            err = true;
-        }
-
-        if (!expectedBlock.equals(UnicodeBlock.forName(idBlockName).toString())) {
-            System.err.println("Error #2: UnicodeBlock.forName(\"" +
-                idBlockName + "\") returned wrong value.\n\tGot: " +
-                UnicodeBlock.forName(idBlockName) +
-                "\n\tExpected: " + expectedBlock);
-            err = true;
-        }
-
-        if (!expectedBlock.equals(UnicodeBlock.forName(regexBlockName).toString())) {
-            System.err.println("Error #3: UnicodeBlock.forName(\"" +
-                regexBlockName + "\") returned wrong value.\n\tGot: " +
-                UnicodeBlock.forName(regexBlockName) +
-                "\n\tExpected: " + expectedBlock);
-            err = true;
-        }
-    }
-
-    /**
-     * now try a bad block name. This should produce an IAE.
-     */
-    private static void test4830803_2() {
-        boolean threwExpected = false;
-
-        try {
-            UnicodeBlock block = UnicodeBlock.forName("notdefined");
-        }
-        catch(IllegalArgumentException e) {
-            threwExpected = true;
-        }
-
-        if (threwExpected == false) {
-            System.err.println("Error: UnicodeBlock.forName(\"notdefined\") should throw IllegalArgumentException.");
-            err = true;
-        }
-    }
-
-    /**
-     * Convert the argument to a block name form used by the regex package.
-     * That is, remove all spaces.
-     */
-    private static String toRegExString(String str) {
-        String[] tokens = null;
-        StringBuilder retStr = new StringBuilder();
-        try {
-                   tokens = str.split(" ");
-        }
-        catch(java.util.regex.PatternSyntaxException e) {
-                   return null;
-        }
-        for(int x=0; x < tokens.length; ++x) {
-            retStr.append(tokens[x]);
-        }
-        return retStr.toString();
-    }
-
-    private static void test4886934(Block blk) {
-        String blkName = blk.getName();
-        String blkOrigName = blk.getOriginalName();
-        int ch =  blk.getBegin();
-        UnicodeBlock block = UnicodeBlock.of(ch);
-
-        if (block == null) {
-            System.err.println("Error: The block for " + blkName +
-                " is missing. Please check java.lang.Character.UnicodeBlock.");
-            err = true;
-            return;
-        }
-
-        // For backward compatibility
-        if (blkName.equals("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS")) {
-            blkName = "COMBINING_MARKS_FOR_SYMBOLS";
-            System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS is replaced with COMBINING_MARKS_FOR_SYMBOLS for backward compatibility.");
-        } else if (blkName.equals("GREEK_AND_COPTIC")) {
-            blkName = "GREEK";
-            System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK for backward compatibility.");
-        } else if (blkName.equals("CYRILLIC_SUPPLEMENT")) {
-            blkName = "CYRILLIC_SUPPLEMENTARY";
-            System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with CYRILLIC_SUPPLEMENTARY for backward compatibility.");
-        }
-
-        String blockName = block.toString();
-        if (!blockName.equals(blkName)) {
-            System.err.println("Error: Begin-of-block character(0x" +
-                Integer.toHexString(ch).toUpperCase() +
-                ") should be in \"" + blkName + "\" block " +
-                "(Block name is \"" + blkOrigName + "\")" +
-                " but found in \"" + blockName + "\" block.");
-            err = true;
-        }
-
-        block = UnicodeBlock.of(++ch);
-        blockName = block.toString();
-        if (!blockName.equals(blkName)) {
-            System.err.println("Error: Character(0x" +
-                Integer.toHexString(ch).toUpperCase() +
-                ") should be in \"" + blkName + "\" block " +
-                "(Block name is \"" + blkOrigName + "\")" +
-                " but found in \"" + blockName + "\" block.");
-            err = true;
-        }
-
-        ch = blk.getEnd();
-        block = UnicodeBlock.of(ch);
-        blockName = block.toString();
-        if (!blockName.equals(blkName)) {
-            System.err.println("Error: End-of-block Character(0x" +
-                Integer.toHexString(ch).toUpperCase() +
-                ") should be in \"" + blkName + "\" block " +
-                "(Block name is \"" + blkOrigName + "\")" +
-                " but found in \"" + blockName + "\" block.");
-            err = true;
-        }
-    }
-
-    // List of all Unicode blocks, their start, and end codepoints.
-    public static HashSet<Block> blocks = new HashSet<>();
-
-    private static void generateBlockList() throws Exception {
-        BufferedReader f = new BufferedReader(new FileReader(new File(System.getProperty("test.src", "."), "Blocks.txt")));
-
-        String line;
-        while ((line = f.readLine()) != null) {
-            if (line.length() == 0 || line.charAt(0) == '#') {
-                continue;
-            }
-
-            int index1 = line.indexOf('.');
-            int begin = Integer.parseInt(line.substring(0, index1), 16);
-            int index2 = line.indexOf(';');
-            int end = Integer.parseInt(line.substring(index1+2, index2), 16);
-            String name = line.substring(index2+1).trim();
-
-            System.out.println("  Adding a Block(" +
-                Integer.toHexString(begin) + ", " + Integer.toHexString(end) +
-                ", " + name + ")");
-            blocks.add(new Block(begin, end, name));
-        }
-        f.close();
-    }
-}
-
-class Block {
-
-    public Block() {
-        blockBegin = 0;
-        blockEnd = 0;
-        blockName = null;
-    }
-
-    public Block(int begin, int end, String name) {
-        blockBegin = begin;
-        blockEnd = end;
-        blockName = name.replaceAll("[ -]", "_").toUpperCase(Locale.ENGLISH);
-        originalBlockName = name;
-    }
-
-    public int getBegin() {
-        return blockBegin;
-    }
-
-    public int getEnd() {
-        return blockEnd;
-    }
-
-    public String getName() {
-        return blockName;
-    }
-
-    public String getOriginalName() {
-        return originalBlockName;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) return false;
-        if (!(obj instanceof Block)) return false;
-
-        Block other = (Block)obj;
-        return other.blockBegin == blockBegin &&
-                other.blockEnd == blockEnd &&
-                other.blockName.equals(blockName) &&
-                other.originalBlockName.equals(originalBlockName);
-    }
-    int blockBegin, blockEnd;
-    String blockName, originalBlockName;
-}
--- a/test/jdk/java/lang/Character/TestISOControls.java	Wed May 23 17:02:13 2018 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @summary  Check that ISO control ranges are valid.
- * @run main TestISOControls
- * @author John O'Conner
- */
-
-public class TestISOControls {
-
-
-  public static void main(String[] args) {
-
-    int[] test = { -1, 0, 0x0010, 0x001F, 0x0020, 0x007E, 0x007F, 0x0090,
-                   0x009F, 0x00A0 };
-    boolean[] expectedResult = { false, true, true, true, false, false, true,
-                                 true, true, false };
-
-    for (int x=0; x < test.length; ++x) {
-      if (Character.isISOControl(test[x]) != expectedResult[x]) {
-          System.out.println("Fail: " + test[x]);
-          throw new RuntimeException();
-      }
-
-    }
-    System.out.println("Passed");
-
-  }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Character/UnicodeBlock/Blocks.txt	Wed May 23 09:33:37 2018 -0700
@@ -0,0 +1,316 @@
+# Blocks-10.0.0.txt
+# Date: 2017-04-12, 17:30:00 GMT [KW]
+# Copyright (c) 2017 Unicode, Inc.
+# For terms of use, see http://www.unicode.org/terms_of_use.html
+#
+# Unicode Character Database
+# For documentation, see http://www.unicode.org/reports/tr44/
+#
+# Format:
+# Start Code..End Code; Block Name
+
+# ================================================
+
+# Note:   When comparing block names, casing, whitespace, hyphens,
+#         and underbars are ignored.
+#         For example, "Latin Extended-A" and "latin extended a" are equivalent.
+#         For more information on the comparison of property values,
+#            see UAX #44: http://www.unicode.org/reports/tr44/
+#
+#  All block ranges start with a value where (cp MOD 16) = 0,
+#  and end with a value where (cp MOD 16) = 15. In other words,
+#  the last hexadecimal digit of the start of range is ...0
+#  and the last hexadecimal digit of the end of range is ...F.
+#  This constraint on block ranges guarantees that allocations
+#  are done in terms of whole columns, and that code chart display
+#  never involves splitting columns in the charts.
+#
+#  All code points not explicitly listed for Block
+#  have the value No_Block.
+
+# Property:	Block
+#
+# @missing: 0000..10FFFF; No_Block
+
+0000..007F; Basic Latin
+0080..00FF; Latin-1 Supplement
+0100..017F; Latin Extended-A
+0180..024F; Latin Extended-B
+0250..02AF; IPA Extensions
+02B0..02FF; Spacing Modifier Letters
+0300..036F; Combining Diacritical Marks
+0370..03FF; Greek and Coptic
+0400..04FF; Cyrillic
+0500..052F; Cyrillic Supplement
+0530..058F; Armenian
+0590..05FF; Hebrew
+0600..06FF; Arabic
+0700..074F; Syriac
+0750..077F; Arabic Supplement
+0780..07BF; Thaana
+07C0..07FF; NKo
+0800..083F; Samaritan
+0840..085F; Mandaic
+0860..086F; Syriac Supplement
+08A0..08FF; Arabic Extended-A
+0900..097F; Devanagari
+0980..09FF; Bengali
+0A00..0A7F; Gurmukhi
+0A80..0AFF; Gujarati
+0B00..0B7F; Oriya
+0B80..0BFF; Tamil
+0C00..0C7F; Telugu
+0C80..0CFF; Kannada
+0D00..0D7F; Malayalam
+0D80..0DFF; Sinhala
+0E00..0E7F; Thai
+0E80..0EFF; Lao
+0F00..0FFF; Tibetan
+1000..109F; Myanmar
+10A0..10FF; Georgian
+1100..11FF; Hangul Jamo
+1200..137F; Ethiopic
+1380..139F; Ethiopic Supplement
+13A0..13FF; Cherokee
+1400..167F; Unified Canadian Aboriginal Syllabics
+1680..169F; Ogham
+16A0..16FF; Runic
+1700..171F; Tagalog
+1720..173F; Hanunoo
+1740..175F; Buhid
+1760..177F; Tagbanwa
+1780..17FF; Khmer
+1800..18AF; Mongolian
+18B0..18FF; Unified Canadian Aboriginal Syllabics Extended
+1900..194F; Limbu
+1950..197F; Tai Le
+1980..19DF; New Tai Lue
+19E0..19FF; Khmer Symbols
+1A00..1A1F; Buginese
+1A20..1AAF; Tai Tham
+1AB0..1AFF; Combining Diacritical Marks Extended
+1B00..1B7F; Balinese
+1B80..1BBF; Sundanese
+1BC0..1BFF; Batak
+1C00..1C4F; Lepcha
+1C50..1C7F; Ol Chiki
+1C80..1C8F; Cyrillic Extended-C
+1CC0..1CCF; Sundanese Supplement
+1CD0..1CFF; Vedic Extensions
+1D00..1D7F; Phonetic Extensions
+1D80..1DBF; Phonetic Extensions Supplement
+1DC0..1DFF; Combining Diacritical Marks Supplement
+1E00..1EFF; Latin Extended Additional
+1F00..1FFF; Greek Extended
+2000..206F; General Punctuation
+2070..209F; Superscripts and Subscripts
+20A0..20CF; Currency Symbols
+20D0..20FF; Combining Diacritical Marks for Symbols
+2100..214F; Letterlike Symbols
+2150..218F; Number Forms
+2190..21FF; Arrows
+2200..22FF; Mathematical Operators
+2300..23FF; Miscellaneous Technical
+2400..243F; Control Pictures
+2440..245F; Optical Character Recognition
+2460..24FF; Enclosed Alphanumerics
+2500..257F; Box Drawing
+2580..259F; Block Elements
+25A0..25FF; Geometric Shapes
+2600..26FF; Miscellaneous Symbols
+2700..27BF; Dingbats
+27C0..27EF; Miscellaneous Mathematical Symbols-A
+27F0..27FF; Supplemental Arrows-A
+2800..28FF; Braille Patterns
+2900..297F; Supplemental Arrows-B
+2980..29FF; Miscellaneous Mathematical Symbols-B
+2A00..2AFF; Supplemental Mathematical Operators
+2B00..2BFF; Miscellaneous Symbols and Arrows
+2C00..2C5F; Glagolitic
+2C60..2C7F; Latin Extended-C
+2C80..2CFF; Coptic
+2D00..2D2F; Georgian Supplement
+2D30..2D7F; Tifinagh
+2D80..2DDF; Ethiopic Extended
+2DE0..2DFF; Cyrillic Extended-A
+2E00..2E7F; Supplemental Punctuation
+2E80..2EFF; CJK Radicals Supplement
+2F00..2FDF; Kangxi Radicals
+2FF0..2FFF; Ideographic Description Characters
+3000..303F; CJK Symbols and Punctuation
+3040..309F; Hiragana
+30A0..30FF; Katakana
+3100..312F; Bopomofo
+3130..318F; Hangul Compatibility Jamo
+3190..319F; Kanbun
+31A0..31BF; Bopomofo Extended
+31C0..31EF; CJK Strokes
+31F0..31FF; Katakana Phonetic Extensions
+3200..32FF; Enclosed CJK Letters and Months
+3300..33FF; CJK Compatibility
+3400..4DBF; CJK Unified Ideographs Extension A
+4DC0..4DFF; Yijing Hexagram Symbols
+4E00..9FFF; CJK Unified Ideographs
+A000..A48F; Yi Syllables
+A490..A4CF; Yi Radicals
+A4D0..A4FF; Lisu
+A500..A63F; Vai
+A640..A69F; Cyrillic Extended-B
+A6A0..A6FF; Bamum
+A700..A71F; Modifier Tone Letters
+A720..A7FF; Latin Extended-D
+A800..A82F; Syloti Nagri
+A830..A83F; Common Indic Number Forms
+A840..A87F; Phags-pa
+A880..A8DF; Saurashtra
+A8E0..A8FF; Devanagari Extended
+A900..A92F; Kayah Li
+A930..A95F; Rejang
+A960..A97F; Hangul Jamo Extended-A
+A980..A9DF; Javanese
+A9E0..A9FF; Myanmar Extended-B
+AA00..AA5F; Cham
+AA60..AA7F; Myanmar Extended-A
+AA80..AADF; Tai Viet
+AAE0..AAFF; Meetei Mayek Extensions
+AB00..AB2F; Ethiopic Extended-A
+AB30..AB6F; Latin Extended-E
+AB70..ABBF; Cherokee Supplement
+ABC0..ABFF; Meetei Mayek
+AC00..D7AF; Hangul Syllables
+D7B0..D7FF; Hangul Jamo Extended-B
+D800..DB7F; High Surrogates
+DB80..DBFF; High Private Use Surrogates
+DC00..DFFF; Low Surrogates
+E000..F8FF; Private Use Area
+F900..FAFF; CJK Compatibility Ideographs
+FB00..FB4F; Alphabetic Presentation Forms
+FB50..FDFF; Arabic Presentation Forms-A
+FE00..FE0F; Variation Selectors
+FE10..FE1F; Vertical Forms
+FE20..FE2F; Combining Half Marks
+FE30..FE4F; CJK Compatibility Forms
+FE50..FE6F; Small Form Variants
+FE70..FEFF; Arabic Presentation Forms-B
+FF00..FFEF; Halfwidth and Fullwidth Forms
+FFF0..FFFF; Specials
+10000..1007F; Linear B Syllabary
+10080..100FF; Linear B Ideograms
+10100..1013F; Aegean Numbers
+10140..1018F; Ancient Greek Numbers
+10190..101CF; Ancient Symbols
+101D0..101FF; Phaistos Disc
+10280..1029F; Lycian
+102A0..102DF; Carian
+102E0..102FF; Coptic Epact Numbers
+10300..1032F; Old Italic
+10330..1034F; Gothic
+10350..1037F; Old Permic
+10380..1039F; Ugaritic
+103A0..103DF; Old Persian
+10400..1044F; Deseret
+10450..1047F; Shavian
+10480..104AF; Osmanya
+104B0..104FF; Osage
+10500..1052F; Elbasan
+10530..1056F; Caucasian Albanian
+10600..1077F; Linear A
+10800..1083F; Cypriot Syllabary
+10840..1085F; Imperial Aramaic
+10860..1087F; Palmyrene
+10880..108AF; Nabataean
+108E0..108FF; Hatran
+10900..1091F; Phoenician
+10920..1093F; Lydian
+10980..1099F; Meroitic Hieroglyphs
+109A0..109FF; Meroitic Cursive
+10A00..10A5F; Kharoshthi
+10A60..10A7F; Old South Arabian
+10A80..10A9F; Old North Arabian
+10AC0..10AFF; Manichaean
+10B00..10B3F; Avestan
+10B40..10B5F; Inscriptional Parthian
+10B60..10B7F; Inscriptional Pahlavi
+10B80..10BAF; Psalter Pahlavi
+10C00..10C4F; Old Turkic
+10C80..10CFF; Old Hungarian
+10E60..10E7F; Rumi Numeral Symbols
+11000..1107F; Brahmi
+11080..110CF; Kaithi
+110D0..110FF; Sora Sompeng
+11100..1114F; Chakma
+11150..1117F; Mahajani
+11180..111DF; Sharada
+111E0..111FF; Sinhala Archaic Numbers
+11200..1124F; Khojki
+11280..112AF; Multani
+112B0..112FF; Khudawadi
+11300..1137F; Grantha
+11400..1147F; Newa
+11480..114DF; Tirhuta
+11580..115FF; Siddham
+11600..1165F; Modi
+11660..1167F; Mongolian Supplement
+11680..116CF; Takri
+11700..1173F; Ahom
+118A0..118FF; Warang Citi
+11A00..11A4F; Zanabazar Square
+11A50..11AAF; Soyombo
+11AC0..11AFF; Pau Cin Hau
+11C00..11C6F; Bhaiksuki
+11C70..11CBF; Marchen
+11D00..11D5F; Masaram Gondi
+12000..123FF; Cuneiform
+12400..1247F; Cuneiform Numbers and Punctuation
+12480..1254F; Early Dynastic Cuneiform
+13000..1342F; Egyptian Hieroglyphs
+14400..1467F; Anatolian Hieroglyphs
+16800..16A3F; Bamum Supplement
+16A40..16A6F; Mro
+16AD0..16AFF; Bassa Vah
+16B00..16B8F; Pahawh Hmong
+16F00..16F9F; Miao
+16FE0..16FFF; Ideographic Symbols and Punctuation
+17000..187FF; Tangut
+18800..18AFF; Tangut Components
+1B000..1B0FF; Kana Supplement
+1B100..1B12F; Kana Extended-A
+1B170..1B2FF; Nushu
+1BC00..1BC9F; Duployan
+1BCA0..1BCAF; Shorthand Format Controls
+1D000..1D0FF; Byzantine Musical Symbols
+1D100..1D1FF; Musical Symbols
+1D200..1D24F; Ancient Greek Musical Notation
+1D300..1D35F; Tai Xuan Jing Symbols
+1D360..1D37F; Counting Rod Numerals
+1D400..1D7FF; Mathematical Alphanumeric Symbols
+1D800..1DAAF; Sutton SignWriting
+1E000..1E02F; Glagolitic Supplement
+1E800..1E8DF; Mende Kikakui
+1E900..1E95F; Adlam
+1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols
+1F000..1F02F; Mahjong Tiles
+1F030..1F09F; Domino Tiles
+1F0A0..1F0FF; Playing Cards
+1F100..1F1FF; Enclosed Alphanumeric Supplement
+1F200..1F2FF; Enclosed Ideographic Supplement
+1F300..1F5FF; Miscellaneous Symbols and Pictographs
+1F600..1F64F; Emoticons
+1F650..1F67F; Ornamental Dingbats
+1F680..1F6FF; Transport and Map Symbols
+1F700..1F77F; Alchemical Symbols
+1F780..1F7FF; Geometric Shapes Extended
+1F800..1F8FF; Supplemental Arrows-C
+1F900..1F9FF; Supplemental Symbols and Pictographs
+20000..2A6DF; CJK Unified Ideographs Extension B
+2A700..2B73F; CJK Unified Ideographs Extension C
+2B740..2B81F; CJK Unified Ideographs Extension D
+2B820..2CEAF; CJK Unified Ideographs Extension E
+2CEB0..2EBEF; CJK Unified Ideographs Extension F
+2F800..2FA1F; CJK Compatibility Ideographs Supplement
+E0000..E007F; Tags
+E0100..E01EF; Variation Selectors Supplement
+F0000..FFFFF; Supplementary Private Use Area-A
+100000..10FFFF; Supplementary Private Use Area-B
+
+# EOF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/Character/UnicodeBlock/CheckBlocks.java	Wed May 23 09:33:37 2018 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4830803 4886934 6565620 6959267 7070436 7198195 8032446 8072600 8202771
+ * @summary  Check that the UnicodeBlock forName() method works as expected and block ranges are correct for all Unicode characters.
+ * @run main CheckBlocks
+ * @author John O'Conner
+ */
+
+import java.lang.Character.UnicodeBlock;
+import java.lang.reflect.Field;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.util.HashSet;
+import java.util.Locale;
+
+public class CheckBlocks {
+
+    static boolean err = false;
+    static Class<?> clazzUnicodeBlock;
+
+    public static void main(String[] args) throws Exception {
+        generateBlockList();
+
+        try {
+            clazzUnicodeBlock = Class.forName("java.lang.Character$UnicodeBlock");
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException("Class.forName(\"java.lang.Character$UnicodeBlock\") failed.");
+        }
+
+        for (Block blk : blocks) {
+            test4830803_1(blk);
+            test4830803_2();
+            test4886934(blk);
+        }
+
+        test8202771();
+
+        if (err) {
+            throw new RuntimeException("Failed");
+        } else {
+            System.out.println("Passed");
+        }
+    }
+
+    /**
+     * Check that the UnicodeBlock forName() method works as expected.
+     */
+    private static void test4830803_1(Block blk) throws Exception {
+
+        /*
+         * Try 3 forms of block name in the forName() method. Each form should
+         * produce the same expected block.
+         */
+        String blkName = blk.getName();
+
+        // For backward compatibility
+        switch (blkName) {
+            case "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS":
+                blkName = "COMBINING_MARKS_FOR_SYMBOLS";
+                System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS"
+                        + " is replaced with COMBINING_MARKS_FOR_SYMBOLS"
+                        + " for backward compatibility.");
+                break;
+            case "GREEK_AND_COPTIC":
+                blkName = "GREEK";
+                System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK"
+                        + " for backward compatibility.");
+                break;
+            case "CYRILLIC_SUPPLEMENT":
+                blkName = "CYRILLIC_SUPPLEMENTARY";
+                System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with"
+                        + " CYRILLIC_SUPPLEMENTARY for backward compatibility.");
+                break;
+            default:
+                break;
+        }
+
+        String expectedBlock = null;
+        try {
+            expectedBlock = clazzUnicodeBlock.getField(blkName).getName();
+        } catch (NoSuchFieldException | SecurityException e) {
+            System.err.println("Error: " + blkName + " was not found.");
+            err = true;
+            return;
+        }
+
+        String canonicalBlockName = blk.getOriginalName();
+        String idBlockName = expectedBlock;
+        String regexBlockName = toRegExString(canonicalBlockName);
+
+        if (regexBlockName == null) {
+            System.err.println("Error: Block name which was processed with regex was null.");
+            err = true;
+            return;
+        }
+
+        if (!expectedBlock.equals(UnicodeBlock.forName(canonicalBlockName).toString())) {
+            System.err.println("Error #1: UnicodeBlock.forName(\"" +
+                    canonicalBlockName + "\") returned wrong value.\n\tGot: " +
+                    UnicodeBlock.forName(canonicalBlockName) +
+                    "\n\tExpected: " + expectedBlock);
+            err = true;
+        }
+
+        if (!expectedBlock.equals(UnicodeBlock.forName(idBlockName).toString())) {
+            System.err.println("Error #2: UnicodeBlock.forName(\"" +
+                    idBlockName + "\") returned wrong value.\n\tGot: " +
+                    UnicodeBlock.forName(idBlockName) +
+                    "\n\tExpected: " + expectedBlock);
+            err = true;
+        }
+
+        if (!expectedBlock.equals(UnicodeBlock.forName(regexBlockName).toString())) {
+            System.err.println("Error #3: UnicodeBlock.forName(\"" +
+                    regexBlockName + "\") returned wrong value.\n\tGot: " +
+                    UnicodeBlock.forName(regexBlockName) +
+                    "\n\tExpected: " + expectedBlock);
+            err = true;
+        }
+    }
+
+    /**
+     * now try a bad block name. This should produce an IAE.
+     */
+    private static void test4830803_2() {
+        boolean threwExpected = false;
+
+        try {
+            UnicodeBlock block = UnicodeBlock.forName("notdefined");
+        }
+        catch(IllegalArgumentException e) {
+            threwExpected = true;
+        }
+
+        if (threwExpected == false) {
+            System.err.println("Error: UnicodeBlock.forName(\"notdefined\") should throw IllegalArgumentException.");
+            err = true;
+        }
+    }
+
+    /**
+     * Convert the argument to a block name form used by the regex package.
+     * That is, remove all spaces.
+     */
+    private static String toRegExString(String str) {
+        String[] tokens = null;
+        StringBuilder retStr = new StringBuilder();
+        try {
+            tokens = str.split(" ");
+        }
+        catch(java.util.regex.PatternSyntaxException e) {
+            return null;
+        }
+        for(int x=0; x < tokens.length; ++x) {
+            retStr.append(tokens[x]);
+        }
+        return retStr.toString();
+    }
+
+    private static void test4886934(Block blk) {
+        String blkName = blk.getName();
+        String blkOrigName = blk.getOriginalName();
+        UnicodeBlock block;
+        String blockName;
+
+        // For backward compatibility
+        switch (blkName) {
+            case "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS":
+                blkName = "COMBINING_MARKS_FOR_SYMBOLS";
+                System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS"
+                        + " is replaced with COMBINING_MARKS_FOR_SYMBOLS"
+                        + " for backward compatibility.");
+                break;
+            case "GREEK_AND_COPTIC":
+                blkName = "GREEK";
+                System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK"
+                        + " for backward compatibility.");
+                break;
+            case "CYRILLIC_SUPPLEMENT":
+                blkName = "CYRILLIC_SUPPLEMENTARY";
+                System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with"
+                        + " CYRILLIC_SUPPLEMENTARY for backward compatibility.");
+                break;
+            default:
+                break;
+        }
+
+        for (int ch = blk.getBegin(); ch <= blk.getEnd(); ch++) {
+            block = UnicodeBlock.of(ch);
+            if (block == null) {
+                System.err.println("Error: The block for " + blkName
+                        + " is missing. Please check java.lang.Character.UnicodeBlock.");
+                err = true;
+                break;
+            }
+            blockName = block.toString();
+            if (!blockName.equals(blkName)) {
+                System.err.println("Error: Character(0x"
+                        + Integer.toHexString(ch).toUpperCase()
+                        + ") should be in \"" + blkName + "\" block "
+                        + "(Block name is \"" + blkOrigName + "\")"
+                        + " but found in \"" + blockName + "\" block.");
+                err = true;
+            }
+        }
+    }
+
+    /**
+     * Check if every Field of Character.UnicodeBlock is a valid Unicode Block.
+     */
+    private static void test8202771() {
+        Field[] fields = clazzUnicodeBlock.getFields();
+
+        for (Field f : fields) {
+            // Handle Deprecated field "SURROGATES_AREA".
+            if (f.getAnnotation(Deprecated.class) != null) {
+                continue;
+            }
+
+            String blkName = f.getName();
+            switch (blkName) {
+                case "COMBINING_MARKS_FOR_SYMBOLS":
+                    validateBlock("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS");
+                    break;
+                case "GREEK":
+                    validateBlock("GREEK_AND_COPTIC");
+                    break;
+                case "CYRILLIC_SUPPLEMENTARY":
+                    validateBlock("CYRILLIC_SUPPLEMENT");
+                    break;
+                default:
+                    validateBlock(blkName);
+                    break;
+            }
+        }
+    }
+
+    private static void validateBlock(String blkName) {
+        for (Block block : blocks) {
+            String blockName = block.getName();
+            if (blockName.equals(blkName)) {
+                return;
+            }
+        }
+        err = true;
+        System.err.println(blkName + " is not a valid Unicode Block.");
+    }
+
+    // List of all Unicode blocks, their start, and end codepoints.
+    public static HashSet<Block> blocks = new HashSet<>();
+
+    private static void generateBlockList() throws Exception {
+        File blockData = new File(System.getProperty("test.src", "."),
+                "Blocks.txt");
+        try (BufferedReader f = new BufferedReader(new FileReader(blockData))) {
+            String line;
+            while ((line = f.readLine()) != null) {
+                if (line.length() == 0 || line.charAt(0) == '#') {
+                    continue;
+                }
+
+                int index1 = line.indexOf('.');
+                int begin = Integer.parseInt(line.substring(0, index1), 16);
+                int index2 = line.indexOf(';');
+                int end = Integer.parseInt(line.substring(index1 + 2, index2), 16);
+                String name = line.substring(index2 + 1).trim();
+
+                System.out.println("  Adding a Block(" + Integer.toHexString(begin) + ", " + Integer.toHexString(end)
+                        + ", " + name + ")");
+                blocks.add(new Block(begin, end, name));
+            }
+        }
+    }
+}
+
+class Block {
+
+    public Block() {
+        blockBegin = 0;
+        blockEnd = 0;
+        blockName = null;
+    }
+
+    public Block(int begin, int end, String name) {
+        blockBegin = begin;
+        blockEnd = end;
+        blockName = name.replaceAll("[ -]", "_").toUpperCase(Locale.ENGLISH);
+        originalBlockName = name;
+    }
+
+    public int getBegin() {
+        return blockBegin;
+    }
+
+    public int getEnd() {
+        return blockEnd;
+    }
+
+    public String getName() {
+        return blockName;
+    }
+
+    public String getOriginalName() {
+        return originalBlockName;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) return false;
+        if (!(obj instanceof Block)) return false;
+
+        Block other = (Block)obj;
+        return other.blockBegin == blockBegin &&
+                other.blockEnd == blockEnd &&
+                other.blockName.equals(blockName) &&
+                other.originalBlockName.equals(originalBlockName);
+    }
+    int blockBegin, blockEnd;
+    String blockName, originalBlockName;
+}
--- a/test/jdk/java/util/ArrayList/IteratorMicroBenchmark.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/ArrayList/IteratorMicroBenchmark.java	Wed May 23 09:33:37 2018 -0700
@@ -27,8 +27,10 @@
  * @run main IteratorMicroBenchmark iterations=1 size=8 warmup=0
  */
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.stream.Collectors.toList;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -43,7 +45,6 @@
 import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
 import java.util.regex.Pattern;
 
 /**
@@ -70,16 +71,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- a/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Wed May 23 09:33:37 2018 -0700
@@ -27,11 +27,14 @@
  * @run main IteratorMicroBenchmark iterations=1 size=8 warmup=0
  */
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.stream.Collectors.summingInt;
 import static java.util.stream.Collectors.toCollection;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -54,7 +57,6 @@
 import java.util.concurrent.PriorityBlockingQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.function.UnaryOperator;
 import java.util.regex.Pattern;
@@ -109,17 +111,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            @SuppressWarnings("deprecation")
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
@@ -556,6 +563,18 @@
                     for (int i = 0; i < iterations; i++) {
                         sum[0] = 0;
                         x.replaceAll(sneakyAdder);
-                        check.sum(sum[0]);}}});
+                        check.sum(sum[0]);}}},
+            new Job(klazz + " equals") {
+                public void work() throws Throwable {
+                    ArrayList<Integer> copy = new ArrayList<>(x);
+                    for (int i = 0; i < iterations; i++) {
+                        if (!x.equals(copy))
+                            throw new AssertionError();}}},
+            new Job(klazz + " hashCode") {
+                public void work() throws Throwable {
+                    int hashCode = Arrays.hashCode(x.toArray());
+                    for (int i = 0; i < iterations; i++) {
+                        if (x.hashCode() != hashCode)
+                            throw new AssertionError();}}});
     }
 }
--- a/test/jdk/java/util/Collection/RemoveMicroBenchmark.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/Collection/RemoveMicroBenchmark.java	Wed May 23 09:33:37 2018 -0700
@@ -27,8 +27,10 @@
  * @run main RemoveMicroBenchmark iterations=1 size=8 warmup=0
  */
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.stream.Collectors.toCollection;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -112,17 +114,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            @SuppressWarnings("deprecation")
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
@@ -504,6 +511,15 @@
     Stream<Job> blockingQueueJobs(BlockingQueue<Integer> x) {
         final String klazz = goodClassName(x.getClass());
         return Stream.of(
+            new Job(klazz + " timed poll()") {
+                public void work() throws Throwable {
+                    int[] sum = new int[1];
+                    for (int i = 0; i < iterations; i++) {
+                        sum[0] = 0;
+                        x.addAll(elements);
+                        for (Integer e; (e = x.poll(0L, TimeUnit.DAYS)) != null; )
+                            sum[0] += e;
+                        check.sum(sum[0]);}}},
             new Job(klazz + " drainTo(sink)") {
                 public void work() throws Throwable {
                     ArrayList<Integer> sink = new ArrayList<>();
--- a/test/jdk/java/util/WeakHashMap/GCDuringIteration.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/WeakHashMap/GCDuringIteration.java	Wed May 23 09:33:37 2018 -0700
@@ -34,6 +34,7 @@
 
 import jdk.test.lib.RandomFactory;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
 import java.util.Iterator;
@@ -44,22 +45,28 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.function.BooleanSupplier;
 
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
 public class GCDuringIteration {
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- a/test/jdk/java/util/concurrent/ArrayBlockingQueue/WhiteBox.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/ArrayBlockingQueue/WhiteBox.java	Wed May 23 09:33:37 2018 -0700
@@ -38,10 +38,12 @@
  * @summary White box tests of implementation details
  */
 
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static org.testng.Assert.*;
 
 import org.testng.annotations.Test;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
@@ -202,16 +204,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, TimeUnit.SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- a/test/jdk/java/util/concurrent/ConcurrentQueues/GCRetention.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/ConcurrentQueues/GCRetention.java	Wed May 23 09:33:37 2018 -0700
@@ -38,8 +38,9 @@
  * @run main GCRetention just-testing
  */
 
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
@@ -65,16 +66,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/concurrent/PriorityBlockingQueue/WhiteBox.java	Wed May 23 09:33:37 2018 -0700
@@ -0,0 +1,270 @@
+/*
+ * 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 file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Martin Buchholz with assistance from members of JCP
+ * JSR-166 Expert Group and released to the public domain, as
+ * explained at http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/*
+ * @test
+ * @modules java.base/java.util.concurrent:open
+ *          java.base/java.util:open
+ * @run testng WhiteBox
+ * @summary White box tests of implementation details
+ */
+
+import static org.testng.Assert.*;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+@Test
+public class WhiteBox {
+    final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+    final VarHandle PQ_QUEUE = queueVarHandle(PriorityQueue.class);
+    final VarHandle PBQ_QUEUE = queueVarHandle(PriorityBlockingQueue.class);
+
+    VarHandle queueVarHandle(Class klazz) {
+        return findVarHandle(klazz, "queue", Object[].class);
+    }
+
+    VarHandle findVarHandle(Class klazz, String fieldName, Class type) {
+        try {
+            return MethodHandles.privateLookupIn(klazz, MethodHandles.lookup())
+                .findVarHandle(klazz, fieldName, type);
+        } catch (ReflectiveOperationException ex) { throw new Error(ex); }
+    }
+
+    Object[] queue(PriorityQueue q) {
+        return (Object[]) PQ_QUEUE.getOpaque(q);
+    }
+
+    Object[] queue(PriorityBlockingQueue q) {
+        return (Object[]) PBQ_QUEUE.getOpaque(q);
+    }
+
+    /** PriorityQueue and PriorityBlockingQueue have identical heap management. */
+    @Test
+    public void randomLockstep() {
+        PriorityBlockingQueue pbq = new PriorityBlockingQueue();
+        PriorityQueue pq = new PriorityQueue();
+        List<Consumer<Queue>> frobbers = List.of(
+            q -> q.add(42),
+            q -> assertTrue(q.offer(86)),
+            q -> q.poll(),
+            q -> q.peek(),
+            q -> {
+                Iterator it = q.iterator();
+                if (it.hasNext()) {
+                    it.next();
+                    it.remove();
+                }});
+        for (int i = 0; i < 100; i++) {
+            Consumer<Queue> frobber = frobbers.get(rnd.nextInt(frobbers.size()));
+            frobber.accept(pq);
+            frobber.accept(pbq);
+            assertInvariants(pbq);
+            assertInvariants(pq);
+            assertTrue(Arrays.equals(pq.toArray(), pbq.toArray()));
+        }
+    }
+
+    @Test
+    public void forgetMeNot_PriorityQueue() {
+        forgetMeNot(() -> new PriorityQueue());
+        forgetMeNot(() -> new PriorityQueue(rnd.nextInt(1, 100)));
+        forgetMeNot(() -> new PriorityQueue(rnd.nextInt(1, 100), Collections.reverseOrder()));
+    }
+
+    @Test
+    public void forgetMeNot_PriorityBlockingQueue() {
+        forgetMeNot(() -> new PriorityBlockingQueue());
+        forgetMeNot(() -> new PriorityBlockingQueue(rnd.nextInt(1, 100)));
+        forgetMeNot(() -> new PriorityBlockingQueue(rnd.nextInt(1, 100), Collections.reverseOrder()));
+    }
+
+    void forgetMeNot(Supplier<Queue> qMaker) {
+        Queue q = qMaker.get();
+        Set replay = Collections.newSetFromMap(new IdentityHashMap());
+        int size = rnd.nextInt(64);
+        for (int i = 0; i < size; i++) {
+            Object e = new Integer(rnd.nextInt());
+            q.add(e);
+            replay.add(e);
+        }
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            Object e = it.next();
+            assertTrue(replay.contains(e));
+            if (rnd.nextBoolean()) {
+                it.remove();
+                if (rnd.nextBoolean())
+                    assertThrows(IllegalStateException.class,
+                                 () -> it.remove());
+                assertTrue(replay.remove(e));
+            }
+            assertInvariants(q);
+        }
+        for (Object e; (e = q.poll()) != null; )
+            assertTrue(replay.remove(e));
+        assertTrue(replay.isEmpty());
+    }
+
+    @Test
+    public void testRemoveIf_PriorityQueue() {
+        testRemoveIf(() -> new PriorityQueue());
+        testRemoveIf(() -> new PriorityQueue(rnd.nextInt(1, 100)));
+        testRemoveIf(() -> new PriorityQueue(rnd.nextInt(1, 100), Collections.reverseOrder()));
+    }
+
+    @Test
+    public void testRemoveIf_PriorityBlockingQueue() {
+        testRemoveIf(() -> new PriorityBlockingQueue());
+        testRemoveIf(() -> new PriorityBlockingQueue(rnd.nextInt(1, 100)));
+        testRemoveIf(() -> new PriorityBlockingQueue(rnd.nextInt(1, 100), Collections.reverseOrder()));
+    }
+
+    void testRemoveIf(Supplier<Queue> qMaker) {
+        Queue q = qMaker.get();
+        Set replay = Collections.newSetFromMap(new IdentityHashMap());
+        int size = rnd.nextInt(64);
+        for (int i = 0; i < size; i++) {
+            Object e = new Integer(rnd.nextInt());
+            q.add(e);
+            replay.add(e);
+        }
+        q.removeIf(
+            e -> {
+                if (rnd.nextBoolean())
+                    return false;
+                assertTrue(replay.remove(e));
+                return true;
+            });
+        assertInvariants(q);
+        for (Object e; (e = q.poll()) != null; )
+            assertTrue(replay.remove(e));
+        assertTrue(replay.isEmpty());
+    }
+
+    byte[] serialBytes(Object o) {
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(o);
+            oos.flush();
+            oos.close();
+            return bos.toByteArray();
+        } catch (Exception fail) {
+            throw new AssertionError(fail);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T serialClone(T o) {
+        try {
+            ObjectInputStream ois = new ObjectInputStream
+                (new ByteArrayInputStream(serialBytes(o)));
+            T clone = (T) ois.readObject();
+            assertNotSame(o, clone);
+            assertSame(o.getClass(), clone.getClass());
+            return clone;
+        } catch (Exception fail) {
+            throw new AssertionError(fail);
+        }
+    }
+
+    @Test
+    public void testSerialization() {
+        assertInvariants(serialClone(new PriorityQueue()));
+        assertInvariants(serialClone(new PriorityQueue(1)));
+        assertInvariants(serialClone(new PriorityQueue(new ArrayList())));
+        assertInvariants(serialClone(new PriorityBlockingQueue()));
+        assertInvariants(serialClone(new PriorityBlockingQueue(1)));
+        assertInvariants(serialClone(new PriorityBlockingQueue(new ArrayList())));
+    }
+
+    void assertInvariants(Queue q) {
+        if (q instanceof PriorityQueue)
+            assertInvariants((PriorityQueue) q);
+        else
+            assertInvariants((PriorityBlockingQueue) q);
+    }
+
+    void assertInvariants(PriorityBlockingQueue q) {
+        assertHeap(queue(q), q.size(), q.comparator());
+    }
+
+    void assertInvariants(PriorityQueue q) {
+        assertHeap(queue(q), q.size(), q.comparator());
+    }
+
+    void assertHeap(Object[] es, int size, Comparator cmp) {
+        assertTrue(es.length > 0);
+        assertTrue(size >= 0 && size <= es.length);
+        if (size < es.length)
+            assertNull(es[size]);
+        if (size > 0)
+            assertNotNull(es[size - 1]);
+        for (int i = 0; i <= size / 2; i++) {
+            int leftChild = 2 * i + 1;
+            int rightChild = leftChild + 1;
+            if (leftChild < size)
+                assertTrue(cmp(es[i], es[leftChild], cmp) <= 0);
+            if (rightChild < size)
+                assertTrue(cmp(es[i], es[rightChild], cmp) <= 0);
+        }
+    }
+
+    int cmp(Object x, Object y, Comparator cmp) {
+        return (cmp == null)
+            ? ((Comparable) x).compareTo(y)
+            : cmp.compare(x, y);
+    }
+
+}
--- a/test/jdk/java/util/concurrent/forkjoin/FJExceptionTableLeak.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/forkjoin/FJExceptionTableLeak.java	Wed May 23 09:33:37 2018 -0700
@@ -40,8 +40,9 @@
  * This whitebox test is sensitive to forkjoin implementation details.
  */
 
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
 
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -115,16 +116,22 @@
 
     /** No guarantees, but effective in practice. */
     static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- a/test/jdk/java/util/concurrent/locks/Lock/TimedAcquireLeak.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/locks/Lock/TimedAcquireLeak.java	Wed May 23 09:33:37 2018 -0700
@@ -31,7 +31,6 @@
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.NANOSECONDS;
-import static java.util.concurrent.TimeUnit.SECONDS;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -41,6 +40,7 @@
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.Reader;
+import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
@@ -125,16 +125,22 @@
 
     /** No guarantees, but effective in practice. */
     private static void forceFullGc() {
-        CountDownLatch finalizeDone = new CountDownLatch(1);
-        WeakReference<?> ref = new WeakReference<Object>(new Object() {
-            protected void finalize() { finalizeDone.countDown(); }});
+        long timeoutMillis = 1000L;
+        CountDownLatch finalized = new CountDownLatch(1);
+        ReferenceQueue<Object> queue = new ReferenceQueue<>();
+        WeakReference<Object> ref = new WeakReference<>(
+            new Object() { protected void finalize() { finalized.countDown(); }},
+            queue);
         try {
-            for (int i = 0; i < 10; i++) {
+            for (int tries = 3; tries--> 0; ) {
                 System.gc();
-                if (finalizeDone.await(1L, SECONDS) && ref.get() == null) {
+                if (finalized.await(timeoutMillis, MILLISECONDS)
+                    && queue.remove(timeoutMillis) != null
+                    && ref.get() == null) {
                     System.runFinalization(); // try to pick up stragglers
                     return;
                 }
+                timeoutMillis *= 4;
             }
         } catch (InterruptedException unexpected) {
             throw new AssertionError("unexpected InterruptedException");
--- a/test/jdk/java/util/concurrent/tck/Collection8Test.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/tck/Collection8Test.java	Wed May 23 09:33:37 2018 -0700
@@ -616,15 +616,32 @@
     public void testRemoveAfterForEachRemaining() {
         Collection c = impl.emptyCollection();
         ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        ArrayList copy = new ArrayList();
+        boolean ordered = c.spliterator().hasCharacteristics(Spliterator.ORDERED);
         testCollection: {
             int n = 3 + rnd.nextInt(2);
-            for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+            for (int i = 0; i < n; i++) {
+                Object x = impl.makeElement(i);
+                c.add(x);
+                copy.add(x);
+            }
             Iterator it = c.iterator();
-            assertTrue(it.hasNext());
-            assertEquals(impl.makeElement(0), it.next());
-            assertTrue(it.hasNext());
-            assertEquals(impl.makeElement(1), it.next());
-            it.forEachRemaining(e -> assertTrue(c.contains(e)));
+            if (ordered) {
+                if (rnd.nextBoolean()) assertTrue(it.hasNext());
+                assertEquals(impl.makeElement(0), it.next());
+                if (rnd.nextBoolean()) assertTrue(it.hasNext());
+                assertEquals(impl.makeElement(1), it.next());
+            } else {
+                if (rnd.nextBoolean()) assertTrue(it.hasNext());
+                assertTrue(copy.contains(it.next()));
+                if (rnd.nextBoolean()) assertTrue(it.hasNext());
+                assertTrue(copy.contains(it.next()));
+            }
+            if (rnd.nextBoolean()) assertTrue(it.hasNext());
+            it.forEachRemaining(
+                e -> {
+                    assertTrue(c.contains(e));
+                    assertTrue(copy.contains(e));});
             if (testImplementationDetails) {
                 if (c instanceof java.util.concurrent.ArrayBlockingQueue) {
                     assertIteratorExhausted(it);
@@ -634,14 +651,17 @@
                         break testCollection;
                     }
                     assertEquals(n - 1, c.size());
-                    for (int i = 0; i < n - 1; i++)
-                        assertTrue(c.contains(impl.makeElement(i)));
-                    assertFalse(c.contains(impl.makeElement(n - 1)));
+                    if (ordered) {
+                        for (int i = 0; i < n - 1; i++)
+                            assertTrue(c.contains(impl.makeElement(i)));
+                        assertFalse(c.contains(impl.makeElement(n - 1)));
+                    }
                 }
             }
         }
         if (c instanceof Deque) {
             Deque d = (Deque) impl.emptyCollection();
+            assertTrue(ordered);
             int n = 3 + rnd.nextInt(2);
             for (int i = 0; i < n; i++) d.add(impl.makeElement(i));
             Iterator it = d.descendingIterator();
@@ -959,6 +979,25 @@
         } catch (java.io.NotSerializableException acceptable) {}
     }
 
+    public void DISABLED_testReplaceAllIsNotStructuralModification() {
+        Collection c = impl.emptyCollection();
+        if (!(c instanceof List))
+            return;
+        List list = (List) c;
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        for (int n = rnd.nextInt(2, 10); n--> 0; )
+            list.add(impl.makeElement(rnd.nextInt()));
+        ArrayList copy = new ArrayList(list);
+        int size = list.size(), half = size / 2;
+        Iterator it = list.iterator();
+        for (int i = 0; i < half; i++)
+            assertEquals(it.next(), copy.get(i));
+        list.replaceAll(n -> n);
+        // ConcurrentModificationException must not be thrown here.
+        for (int i = half; i < size; i++)
+            assertEquals(it.next(), copy.get(i));
+    }
+
 //     public void testCollection8DebugFail() {
 //         fail(impl.klazz().getSimpleName());
 //     }
--- a/test/jdk/java/util/concurrent/tck/CopyOnWriteArraySetTest.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/tck/CopyOnWriteArraySetTest.java	Wed May 23 09:33:37 2018 -0700
@@ -42,7 +42,6 @@
 import java.util.concurrent.CopyOnWriteArraySet;
 
 import junit.framework.Test;
-import junit.framework.TestSuite;
 
 public class CopyOnWriteArraySetTest extends JSR166TestCase {
     public static void main(String[] args) {
--- a/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/tck/PriorityBlockingQueueTest.java	Wed May 23 09:33:37 2018 -0700
@@ -47,6 +47,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.ThreadLocalRandom;
 
 import junit.framework.Test;
 
@@ -60,7 +61,9 @@
 
     public static class InitialCapacity extends BlockingQueueTest {
         protected BlockingQueue emptyCollection() {
-            return new PriorityBlockingQueue(SIZE);
+            ThreadLocalRandom rnd = ThreadLocalRandom.current();
+            int initialCapacity = rnd.nextInt(1, SIZE);
+            return new PriorityBlockingQueue(initialCapacity);
         }
     }
 
@@ -71,19 +74,35 @@
     public static Test suite() {
         class Implementation implements CollectionImplementation {
             public Class<?> klazz() { return PriorityBlockingQueue.class; }
-            public Collection emptyCollection() { return new PriorityBlockingQueue(); }
+            public Collection emptyCollection() {
+                return new PriorityBlockingQueue();
+            }
             public Object makeElement(int i) { return i; }
             public boolean isConcurrent() { return true; }
             public boolean permitsNulls() { return false; }
         }
-        return newTestSuite(PriorityBlockingQueueTest.class,
-                            new Generic().testSuite(),
-                            new InitialCapacity().testSuite(),
-                            CollectionTest.testSuite(new Implementation()));
+        class ComparatorImplementation implements CollectionImplementation {
+            public Class<?> klazz() { return PriorityBlockingQueue.class; }
+            public Collection emptyCollection() {
+                ThreadLocalRandom rnd = ThreadLocalRandom.current();
+                int initialCapacity = rnd.nextInt(1, 10);
+                return new PriorityBlockingQueue(
+                    initialCapacity, new MyReverseComparator());
+            }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(
+            PriorityBlockingQueueTest.class,
+            new Generic().testSuite(),
+            new InitialCapacity().testSuite(),
+            CollectionTest.testSuite(new Implementation()),
+            CollectionTest.testSuite(new ComparatorImplementation()));
     }
 
     /** Sample Comparator */
-    static class MyReverseComparator implements Comparator {
+    static class MyReverseComparator implements Comparator, java.io.Serializable {
         public int compare(Object x, Object y) {
             return ((Comparable)y).compareTo(x);
         }
--- a/test/jdk/java/util/concurrent/tck/PriorityQueueTest.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/tck/PriorityQueueTest.java	Wed May 23 09:33:37 2018 -0700
@@ -55,11 +55,22 @@
             public boolean isConcurrent() { return false; }
             public boolean permitsNulls() { return false; }
         }
-        return newTestSuite(PriorityQueueTest.class,
-                            CollectionTest.testSuite(new Implementation()));
+        class ComparatorImplementation implements CollectionImplementation {
+            public Class<?> klazz() { return PriorityQueue.class; }
+            public Collection emptyCollection() {
+                return new PriorityQueue(new MyReverseComparator());
+            }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(
+            PriorityQueueTest.class,
+            CollectionTest.testSuite(new Implementation()),
+            CollectionTest.testSuite(new ComparatorImplementation()));
     }
 
-    static class MyReverseComparator implements Comparator {
+    static class MyReverseComparator implements Comparator, java.io.Serializable {
         public int compare(Object x, Object y) {
             return ((Comparable)y).compareTo(x);
         }
--- a/test/jdk/java/util/concurrent/tck/VectorTest.java	Wed May 23 17:02:13 2018 +0800
+++ b/test/jdk/java/util/concurrent/tck/VectorTest.java	Wed May 23 09:33:37 2018 -0700
@@ -32,7 +32,6 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;