ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ConcurrentHashMap.java (file contents):
Revision 1.239 by jsr166, Fri Jul 19 19:34:43 2013 UTC vs.
Revision 1.318 by jsr166, Sat Aug 10 16:48:05 2019 UTC

# Line 13 | Line 13 | import java.lang.reflect.Type;
13   import java.util.AbstractMap;
14   import java.util.Arrays;
15   import java.util.Collection;
16 import java.util.Comparator;
17 import java.util.ConcurrentModificationException;
16   import java.util.Enumeration;
17   import java.util.HashMap;
18   import java.util.Hashtable;
# Line 23 | Line 21 | import java.util.Map;
21   import java.util.NoSuchElementException;
22   import java.util.Set;
23   import java.util.Spliterator;
26 import java.util.concurrent.ConcurrentMap;
27 import java.util.concurrent.ForkJoinPool;
24   import java.util.concurrent.atomic.AtomicReference;
25   import java.util.concurrent.locks.LockSupport;
26   import java.util.concurrent.locks.ReentrantLock;
27   import java.util.function.BiConsumer;
28   import java.util.function.BiFunction;
33 import java.util.function.BinaryOperator;
29   import java.util.function.Consumer;
30   import java.util.function.DoubleBinaryOperator;
31   import java.util.function.Function;
32   import java.util.function.IntBinaryOperator;
33   import java.util.function.LongBinaryOperator;
34 + import java.util.function.Predicate;
35   import java.util.function.ToDoubleBiFunction;
36   import java.util.function.ToDoubleFunction;
37   import java.util.function.ToIntBiFunction;
# Line 43 | Line 39 | import java.util.function.ToIntFunction;
39   import java.util.function.ToLongBiFunction;
40   import java.util.function.ToLongFunction;
41   import java.util.stream.Stream;
42 + import jdk.internal.misc.Unsafe;
43  
44   /**
45   * A hash table supporting full concurrency of retrievals and
# Line 65 | Line 62 | import java.util.stream.Stream;
62   * that key reporting the updated value.)  For aggregate operations
63   * such as {@code putAll} and {@code clear}, concurrent retrievals may
64   * reflect insertion or removal of only some entries.  Similarly,
65 < * Iterators and Enumerations return elements reflecting the state of
66 < * the hash table at some point at or since the creation of the
65 > * Iterators, Spliterators and Enumerations return elements reflecting the
66 > * state of the hash table at some point at or since the creation of the
67   * iterator/enumeration.  They do <em>not</em> throw {@link
68 < * ConcurrentModificationException}.  However, iterators are designed
69 < * to be used by only one thread at a time.  Bear in mind that the
70 < * results of aggregate status methods including {@code size}, {@code
71 < * isEmpty}, and {@code containsValue} are typically useful only when
72 < * a map is not undergoing concurrent updates in other threads.
68 > * java.util.ConcurrentModificationException ConcurrentModificationException}.
69 > * However, iterators are designed to be used by only one thread at a time.
70 > * Bear in mind that the results of aggregate status methods including
71 > * {@code size}, {@code isEmpty}, and {@code containsValue} are typically
72 > * useful only when a map is not undergoing concurrent updates in other threads.
73   * Otherwise the results of these methods reflect transient states
74   * that may be adequate for monitoring or estimation purposes, but not
75   * for program control.
# Line 105 | Line 102 | import java.util.stream.Stream;
102   * mapped values are (perhaps transiently) not used or all take the
103   * same mapping value.
104   *
105 < * <p>A ConcurrentHashMap can be used as scalable frequency map (a
105 > * <p>A ConcurrentHashMap can be used as a scalable frequency map (a
106   * form of histogram or multiset) by using {@link
107   * java.util.concurrent.atomic.LongAdder} values and initializing via
108   * {@link #computeIfAbsent computeIfAbsent}. For example, to add a count
109   * to a {@code ConcurrentHashMap<String,LongAdder> freqs}, you can use
110 < * {@code freqs.computeIfAbsent(k -> new LongAdder()).increment();}
110 > * {@code freqs.computeIfAbsent(key, k -> new LongAdder()).increment();}
111   *
112   * <p>This class and its views and iterators implement all of the
113   * <em>optional</em> methods of the {@link Map} and {@link Iterator}
# Line 125 | Line 122 | import java.util.stream.Stream;
122   * being concurrently updated by other threads; for example, when
123   * computing a snapshot summary of the values in a shared registry.
124   * There are three kinds of operation, each with four forms, accepting
125 < * functions with Keys, Values, Entries, and (Key, Value) arguments
126 < * and/or return values. Because the elements of a ConcurrentHashMap
127 < * are not ordered in any particular way, and may be processed in
128 < * different orders in different parallel executions, the correctness
129 < * of supplied functions should not depend on any ordering, or on any
130 < * other objects or values that may transiently change while
131 < * computation is in progress; and except for forEach actions, should
132 < * ideally be side-effect-free. Bulk operations on {@link java.util.Map.Entry}
133 < * objects do not support method {@code setValue}.
125 > * functions with keys, values, entries, and (key, value) pairs as
126 > * arguments and/or return values. Because the elements of a
127 > * ConcurrentHashMap are not ordered in any particular way, and may be
128 > * processed in different orders in different parallel executions, the
129 > * correctness of supplied functions should not depend on any
130 > * ordering, or on any other objects or values that may transiently
131 > * change while computation is in progress; and except for forEach
132 > * actions, should ideally be side-effect-free. Bulk operations on
133 > * {@link Map.Entry} objects do not support method {@code setValue}.
134   *
135   * <ul>
136 < * <li> forEach: Perform a given action on each element.
136 > * <li>forEach: Performs a given action on each element.
137   * A variant form applies a given transformation on each element
138 < * before performing the action.</li>
138 > * before performing the action.
139   *
140 < * <li> search: Return the first available non-null result of
140 > * <li>search: Returns the first available non-null result of
141   * applying a given function on each element; skipping further
142 < * search when a result is found.</li>
142 > * search when a result is found.
143   *
144 < * <li> reduce: Accumulate each element.  The supplied reduction
144 > * <li>reduce: Accumulates each element.  The supplied reduction
145   * function cannot rely on ordering (more formally, it should be
146   * both associative and commutative).  There are five variants:
147   *
148   * <ul>
149   *
150 < * <li> Plain reductions. (There is not a form of this method for
150 > * <li>Plain reductions. (There is not a form of this method for
151   * (key, value) function arguments since there is no corresponding
152 < * return type.)</li>
152 > * return type.)
153   *
154 < * <li> Mapped reductions that accumulate the results of a given
155 < * function applied to each element.</li>
154 > * <li>Mapped reductions that accumulate the results of a given
155 > * function applied to each element.
156   *
157 < * <li> Reductions to scalar doubles, longs, and ints, using a
158 < * given basis value.</li>
157 > * <li>Reductions to scalar doubles, longs, and ints, using a
158 > * given basis value.
159   *
160   * </ul>
164 * </li>
161   * </ul>
162   *
163   * <p>These bulk operations accept a {@code parallelismThreshold}
# Line 228 | Line 224 | import java.util.stream.Stream;
224   * <p>All arguments to all task methods must be non-null.
225   *
226   * <p>This class is a member of the
227 < * <a href="{@docRoot}/../technotes/guides/collections/index.html">
227 > * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
228   * Java Collections Framework</a>.
229   *
230   * @since 1.5
# Line 236 | Line 232 | import java.util.stream.Stream;
232   * @param <K> the type of keys maintained by this map
233   * @param <V> the type of mapped values
234   */
235 < public class ConcurrentHashMap<K,V> extends AbstractMap<K,V> implements ConcurrentMap<K,V>, Serializable {
235 > public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
236 >    implements ConcurrentMap<K,V>, Serializable {
237      private static final long serialVersionUID = 7249069246763182397L;
238  
239      /*
# Line 271 | Line 268 | public class ConcurrentHashMap<K,V> exte
268       * Table accesses require volatile/atomic reads, writes, and
269       * CASes.  Because there is no other way to arrange this without
270       * adding further indirections, we use intrinsics
271 <     * (sun.misc.Unsafe) operations.
271 >     * (jdk.internal.misc.Unsafe) operations.
272       *
273       * We use the top (sign) bit of Node hash fields for control
274       * purposes -- it is available anyway because of addressing
# Line 344 | Line 341 | public class ConcurrentHashMap<K,V> exte
341       * The table is resized when occupancy exceeds a percentage
342       * threshold (nominally, 0.75, but see below).  Any thread
343       * noticing an overfull bin may assist in resizing after the
344 <     * initiating thread allocates and sets up the replacement
345 <     * array. However, rather than stalling, these other threads may
346 <     * proceed with insertions etc.  The use of TreeBins shields us
347 <     * from the worst case effects of overfilling while resizes are in
344 >     * initiating thread allocates and sets up the replacement array.
345 >     * However, rather than stalling, these other threads may proceed
346 >     * with insertions etc.  The use of TreeBins shields us from the
347 >     * worst case effects of overfilling while resizes are in
348       * progress.  Resizing proceeds by transferring bins, one by one,
349 <     * from the table to the next table. To enable concurrency, the
350 <     * next table must be (incrementally) prefilled with place-holders
351 <     * serving as reverse forwarders to the old table.  Because we are
349 >     * from the table to the next table. However, threads claim small
350 >     * blocks of indices to transfer (via field transferIndex) before
351 >     * doing so, reducing contention.  A generation stamp in field
352 >     * sizeCtl ensures that resizings do not overlap. Because we are
353       * using power-of-two expansion, the elements from each bin must
354       * either stay at same index, or move with a power of two
355       * offset. We eliminate unnecessary node creation by catching
356       * cases where old nodes can be reused because their next fields
357       * won't change.  On average, only about one-sixth of them need
358       * cloning when a table doubles. The nodes they replace will be
359 <     * garbage collectable as soon as they are no longer referenced by
359 >     * garbage collectible as soon as they are no longer referenced by
360       * any reader thread that may be in the midst of concurrently
361       * traversing table.  Upon transfer, the old table bin contains
362       * only a special forwarding node (with hash field "MOVED") that
# Line 372 | Line 370 | public class ConcurrentHashMap<K,V> exte
370       * locks, average aggregate waits become shorter as resizing
371       * progresses.  The transfer operation must also ensure that all
372       * accessible bins in both the old and new table are usable by any
373 <     * traversal.  This is arranged by proceeding from the last bin
374 <     * (table.length - 1) up towards the first.  Upon seeing a
375 <     * forwarding node, traversals (see class Traverser) arrange to
376 <     * move to the new table without revisiting nodes.  However, to
377 <     * ensure that no intervening nodes are skipped, bin splitting can
378 <     * only begin after the associated reverse-forwarders are in
379 <     * place.
373 >     * traversal.  This is arranged in part by proceeding from the
374 >     * last bin (table.length - 1) up towards the first.  Upon seeing
375 >     * a forwarding node, traversals (see class Traverser) arrange to
376 >     * move to the new table without revisiting nodes.  To ensure that
377 >     * no intervening nodes are skipped even when moved out of order,
378 >     * a stack (see class TableStack) is created on first encounter of
379 >     * a forwarding node during a traversal, to maintain its place if
380 >     * later processing the current table. The need for these
381 >     * save/restore mechanics is relatively rare, but when one
382 >     * forwarding node is encountered, typically many more will be.
383 >     * So Traversers use a simple caching scheme to avoid creating so
384 >     * many new TableStack nodes. (Thanks to Peter Levart for
385 >     * suggesting use of a stack here.)
386       *
387       * The traversal scheme also applies to partial traversals of
388       * ranges of bins (via an alternate Traverser constructor)
# Line 410 | Line 414 | public class ConcurrentHashMap<K,V> exte
414       * related operations (which is the main reason we cannot use
415       * existing collections such as TreeMaps). TreeBins contain
416       * Comparable elements, but may contain others, as well as
417 <     * elements that are Comparable but not necessarily Comparable
418 <     * for the same T, so we cannot invoke compareTo among them. To
419 <     * handle this, the tree is ordered primarily by hash value, then
420 <     * by Comparable.compareTo order if applicable.  On lookup at a
421 <     * node, if elements are not comparable or compare as 0 then both
422 <     * left and right children may need to be searched in the case of
423 <     * tied hash values. (This corresponds to the full list search
424 <     * that would be necessary if all elements were non-Comparable and
425 <     * had tied hashes.)  The red-black balancing code is updated from
426 <     * pre-jdk-collections
417 >     * elements that are Comparable but not necessarily Comparable for
418 >     * the same T, so we cannot invoke compareTo among them. To handle
419 >     * this, the tree is ordered primarily by hash value, then by
420 >     * Comparable.compareTo order if applicable.  On lookup at a node,
421 >     * if elements are not comparable or compare as 0 then both left
422 >     * and right children may need to be searched in the case of tied
423 >     * hash values. (This corresponds to the full list search that
424 >     * would be necessary if all elements were non-Comparable and had
425 >     * tied hashes.) On insertion, to keep a total ordering (or as
426 >     * close as is required here) across rebalancings, we compare
427 >     * classes and identityHashCodes as tie-breakers. The red-black
428 >     * balancing code is updated from pre-jdk-collections
429       * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java)
430       * based in turn on Cormen, Leiserson, and Rivest "Introduction to
431       * Algorithms" (CLR).
# Line 442 | Line 448 | public class ConcurrentHashMap<K,V> exte
448       *
449       * Maintaining API and serialization compatibility with previous
450       * versions of this class introduces several oddities. Mainly: We
451 <     * leave untouched but unused constructor arguments refering to
451 >     * leave untouched but unused constructor arguments referring to
452       * concurrencyLevel. We accept a loadFactor constructor argument,
453       * but apply it only to initial table capacity (which is the only
454       * time that we can guarantee to honor it.) We also declare an
455       * unused "Segment" class that is instantiated in minimal form
456       * only when serializing.
457       *
458 +     * Also, solely for compatibility with previous versions of this
459 +     * class, it extends AbstractMap, even though all of its methods
460 +     * are overridden, so it is just useless baggage.
461 +     *
462       * This file is organized to make things a little easier to follow
463       * while reading than they might otherwise: First the main static
464       * declarations and utilities, then fields, then main public
# Line 529 | Line 539 | public class ConcurrentHashMap<K,V> exte
539       */
540      private static final int MIN_TRANSFER_STRIDE = 16;
541  
542 +    /**
543 +     * The number of bits used for generation stamp in sizeCtl.
544 +     * Must be at least 6 for 32bit arrays.
545 +     */
546 +    private static final int RESIZE_STAMP_BITS = 16;
547 +
548 +    /**
549 +     * The maximum number of threads that can help resize.
550 +     * Must fit in 32 - RESIZE_STAMP_BITS bits.
551 +     */
552 +    private static final int MAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1;
553 +
554 +    /**
555 +     * The bit shift for recording size stamp in sizeCtl.
556 +     */
557 +    private static final int RESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS;
558 +
559      /*
560       * Encodings for Node hash fields. See above for explanation.
561       */
# Line 540 | Line 567 | public class ConcurrentHashMap<K,V> exte
567      /** Number of CPUS, to place bounds on some sizings */
568      static final int NCPU = Runtime.getRuntime().availableProcessors();
569  
570 <    /** For serialization compatibility. */
570 >    /**
571 >     * Serialized pseudo-fields, provided only for jdk7 compatibility.
572 >     * @serialField segments Segment[]
573 >     *   The segments, each of which is a specialized hash table.
574 >     * @serialField segmentMask int
575 >     *   Mask value for indexing into segments. The upper bits of a
576 >     *   key's hash code are used to choose the segment.
577 >     * @serialField segmentShift int
578 >     *   Shift value for indexing within segments.
579 >     */
580      private static final ObjectStreamField[] serialPersistentFields = {
581          new ObjectStreamField("segments", Segment[].class),
582          new ObjectStreamField("segmentMask", Integer.TYPE),
583 <        new ObjectStreamField("segmentShift", Integer.TYPE)
583 >        new ObjectStreamField("segmentShift", Integer.TYPE),
584      };
585  
586      /* ---------------- Nodes -------------- */
# Line 563 | Line 599 | public class ConcurrentHashMap<K,V> exte
599          volatile V val;
600          volatile Node<K,V> next;
601  
602 <        Node(int hash, K key, V val, Node<K,V> next) {
602 >        Node(int hash, K key, V val) {
603              this.hash = hash;
604              this.key = key;
605              this.val = val;
606 +        }
607 +
608 +        Node(int hash, K key, V val, Node<K,V> next) {
609 +            this(hash, key, val);
610              this.next = next;
611          }
612  
613 <        public final K getKey()       { return key; }
614 <        public final V getValue()     { return val; }
615 <        public final int hashCode()   { return key.hashCode() ^ val.hashCode(); }
616 <        public final String toString(){ return key + "=" + val; }
613 >        public final K getKey()     { return key; }
614 >        public final V getValue()   { return val; }
615 >        public final int hashCode() { return key.hashCode() ^ val.hashCode(); }
616 >        public final String toString() {
617 >            return Helpers.mapEntryToString(key, val);
618 >        }
619          public final V setValue(V value) {
620              throw new UnsupportedOperationException();
621          }
# Line 631 | Line 673 | public class ConcurrentHashMap<K,V> exte
673       * See Hackers Delight, sec 3.2
674       */
675      private static final int tableSizeFor(int c) {
676 <        int n = c - 1;
635 <        n |= n >>> 1;
636 <        n |= n >>> 2;
637 <        n |= n >>> 4;
638 <        n |= n >>> 8;
639 <        n |= n >>> 16;
676 >        int n = -1 >>> Integer.numberOfLeadingZeros(c - 1);
677          return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
678      }
679  
# Line 646 | Line 683 | public class ConcurrentHashMap<K,V> exte
683       */
684      static Class<?> comparableClassFor(Object x) {
685          if (x instanceof Comparable) {
686 <            Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
686 >            Class<?> c; Type[] ts, as; ParameterizedType p;
687              if ((c = x.getClass()) == String.class) // bypass checks
688                  return c;
689              if ((ts = c.getGenericInterfaces()) != null) {
690 <                for (int i = 0; i < ts.length; ++i) {
691 <                    if (((t = ts[i]) instanceof ParameterizedType) &&
690 >                for (Type t : ts) {
691 >                    if ((t instanceof ParameterizedType) &&
692                          ((p = (ParameterizedType)t).getRawType() ==
693                           Comparable.class) &&
694                          (as = p.getActualTypeArguments()) != null &&
# Line 676 | Line 713 | public class ConcurrentHashMap<K,V> exte
713      /* ---------------- Table element access -------------- */
714  
715      /*
716 <     * Volatile access methods are used for table elements as well as
716 >     * Atomic access methods are used for table elements as well as
717       * elements of in-progress next table while resizing.  All uses of
718       * the tab arguments must be null checked by callers.  All callers
719       * also paranoically precheck that tab's length is not zero (or an
# Line 686 | Line 723 | public class ConcurrentHashMap<K,V> exte
723       * errors by users, these checks must operate on local variables,
724       * which accounts for some odd-looking inline assignments below.
725       * Note that calls to setTabAt always occur within locked regions,
726 <     * and so in principle require only release ordering, not need
690 <     * full volatile semantics, but are currently coded as volatile
691 <     * writes to be conservative.
726 >     * and so require only release ordering.
727       */
728  
729      @SuppressWarnings("unchecked")
730      static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
731 <        return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
731 >        return (Node<K,V>)U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE);
732      }
733  
734      static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
735                                          Node<K,V> c, Node<K,V> v) {
736 <        return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
736 >        return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
737      }
738  
739      static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
740 <        U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
740 >        U.putObjectRelease(tab, ((long)i << ASHIFT) + ABASE, v);
741      }
742  
743      /* ---------------- Fields -------------- */
# Line 741 | Line 776 | public class ConcurrentHashMap<K,V> exte
776      private transient volatile int transferIndex;
777  
778      /**
744     * The least available table index to split while resizing.
745     */
746    private transient volatile int transferOrigin;
747
748    /**
779       * Spinlock (locked via CAS) used when resizing and/or creating CounterCells.
780       */
781      private transient volatile int cellsBusy;
# Line 780 | Line 810 | public class ConcurrentHashMap<K,V> exte
810       * elements is negative
811       */
812      public ConcurrentHashMap(int initialCapacity) {
813 <        if (initialCapacity < 0)
784 <            throw new IllegalArgumentException();
785 <        int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?
786 <                   MAXIMUM_CAPACITY :
787 <                   tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));
788 <        this.sizeCtl = cap;
813 >        this(initialCapacity, LOAD_FACTOR, 1);
814      }
815  
816      /**
# Line 819 | Line 844 | public class ConcurrentHashMap<K,V> exte
844  
845      /**
846       * Creates a new, empty map with an initial table size based on
847 <     * the given number of elements ({@code initialCapacity}), table
848 <     * density ({@code loadFactor}), and number of concurrently
847 >     * the given number of elements ({@code initialCapacity}), initial
848 >     * table density ({@code loadFactor}), and number of concurrently
849       * updating threads ({@code concurrencyLevel}).
850       *
851       * @param initialCapacity the initial capacity. The implementation
# Line 958 | Line 983 | public class ConcurrentHashMap<K,V> exte
983          int hash = spread(key.hashCode());
984          int binCount = 0;
985          for (Node<K,V>[] tab = table;;) {
986 <            Node<K,V> f; int n, i, fh;
986 >            Node<K,V> f; int n, i, fh; K fk; V fv;
987              if (tab == null || (n = tab.length) == 0)
988                  tab = initTable();
989              else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
990 <                if (casTabAt(tab, i, null,
966 <                             new Node<K,V>(hash, key, value, null)))
990 >                if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))
991                      break;                   // no lock when adding to empty bin
992              }
993              else if ((fh = f.hash) == MOVED)
994                  tab = helpTransfer(tab, f);
995 +            else if (onlyIfAbsent // check first node without acquiring lock
996 +                     && fh == hash
997 +                     && ((fk = f.key) == key || (fk != null && key.equals(fk)))
998 +                     && (fv = f.val) != null)
999 +                return fv;
1000              else {
1001                  V oldVal = null;
1002                  synchronized (f) {
# Line 986 | Line 1015 | public class ConcurrentHashMap<K,V> exte
1015                                  }
1016                                  Node<K,V> pred = e;
1017                                  if ((e = e.next) == null) {
1018 <                                    pred.next = new Node<K,V>(hash, key,
990 <                                                              value, null);
1018 >                                    pred.next = new Node<K,V>(hash, key, value);
1019                                      break;
1020                                  }
1021                              }
# Line 1002 | Line 1030 | public class ConcurrentHashMap<K,V> exte
1030                                      p.val = value;
1031                              }
1032                          }
1033 +                        else if (f instanceof ReservationNode)
1034 +                            throw new IllegalStateException("Recursive update");
1035                      }
1036                  }
1037                  if (binCount != 0) {
# Line 1104 | Line 1134 | public class ConcurrentHashMap<K,V> exte
1134                                  }
1135                              }
1136                          }
1137 +                        else if (f instanceof ReservationNode)
1138 +                            throw new IllegalStateException("Recursive update");
1139                      }
1140                  }
1141                  if (validated) {
# Line 1164 | Line 1196 | public class ConcurrentHashMap<K,V> exte
1196       * operations.  It does not support the {@code add} or
1197       * {@code addAll} operations.
1198       *
1199 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1200 <     * that will never throw {@link ConcurrentModificationException},
1201 <     * and guarantees to traverse elements as they existed upon
1202 <     * construction of the iterator, and may (but is not guaranteed to)
1203 <     * reflect any modifications subsequent to construction.
1199 >     * <p>The view's iterators and spliterators are
1200 >     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1201 >     *
1202 >     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
1203 >     * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
1204       *
1205       * @return the set view
1206       */
1207      public KeySetView<K,V> keySet() {
1208          KeySetView<K,V> ks;
1209 <        return (ks = keySet) != null ? ks : (keySet = new KeySetView<K,V>(this, null));
1209 >        if ((ks = keySet) != null) return ks;
1210 >        return keySet = new KeySetView<K,V>(this, null);
1211      }
1212  
1213      /**
# Line 1187 | Line 1220 | public class ConcurrentHashMap<K,V> exte
1220       * {@code retainAll}, and {@code clear} operations.  It does not
1221       * support the {@code add} or {@code addAll} operations.
1222       *
1223 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1224 <     * that will never throw {@link ConcurrentModificationException},
1225 <     * and guarantees to traverse elements as they existed upon
1226 <     * construction of the iterator, and may (but is not guaranteed to)
1227 <     * reflect any modifications subsequent to construction.
1223 >     * <p>The view's iterators and spliterators are
1224 >     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1225 >     *
1226 >     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT}
1227 >     * and {@link Spliterator#NONNULL}.
1228       *
1229       * @return the collection view
1230       */
1231      public Collection<V> values() {
1232          ValuesView<K,V> vs;
1233 <        return (vs = values) != null ? vs : (values = new ValuesView<K,V>(this));
1233 >        if ((vs = values) != null) return vs;
1234 >        return values = new ValuesView<K,V>(this);
1235      }
1236  
1237      /**
# Line 1209 | Line 1243 | public class ConcurrentHashMap<K,V> exte
1243       * {@code removeAll}, {@code retainAll}, and {@code clear}
1244       * operations.
1245       *
1246 <     * <p>The view's {@code iterator} is a "weakly consistent" iterator
1247 <     * that will never throw {@link ConcurrentModificationException},
1248 <     * and guarantees to traverse elements as they existed upon
1249 <     * construction of the iterator, and may (but is not guaranteed to)
1250 <     * reflect any modifications subsequent to construction.
1246 >     * <p>The view's iterators and spliterators are
1247 >     * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
1248 >     *
1249 >     * <p>The view's {@code spliterator} reports {@link Spliterator#CONCURRENT},
1250 >     * {@link Spliterator#DISTINCT}, and {@link Spliterator#NONNULL}.
1251       *
1252       * @return the set view
1253       */
1254      public Set<Map.Entry<K,V>> entrySet() {
1255          EntrySetView<K,V> es;
1256 <        return (es = entrySet) != null ? es : (entrySet = new EntrySetView<K,V>(this));
1256 >        if ((es = entrySet) != null) return es;
1257 >        return entrySet = new EntrySetView<K,V>(this);
1258      }
1259  
1260      /**
# Line 1311 | Line 1346 | public class ConcurrentHashMap<K,V> exte
1346  
1347      /**
1348       * Stripped-down version of helper class used in previous version,
1349 <     * declared for the sake of serialization compatibility
1349 >     * declared for the sake of serialization compatibility.
1350       */
1351      static class Segment<K,V> extends ReentrantLock implements Serializable {
1352          private static final long serialVersionUID = 2249069246763182397L;
# Line 1320 | Line 1355 | public class ConcurrentHashMap<K,V> exte
1355      }
1356  
1357      /**
1358 <     * Saves the state of the {@code ConcurrentHashMap} instance to a
1359 <     * stream (i.e., serializes it).
1358 >     * Saves this map to a stream (that is, serializes it).
1359 >     *
1360       * @param s the stream
1361       * @throws java.io.IOException if an I/O error occurs
1362       * @serialData
1363 <     * the key (Object) and value (Object)
1364 <     * for each key-value mapping, followed by a null pair.
1363 >     * the serialized fields, followed by the key (Object) and value
1364 >     * (Object) for each key-value mapping, followed by a null pair.
1365       * The key-value mappings are emitted in no particular order.
1366       */
1367      private void writeObject(java.io.ObjectOutputStream s)
# Line 1341 | Line 1376 | public class ConcurrentHashMap<K,V> exte
1376          }
1377          int segmentShift = 32 - sshift;
1378          int segmentMask = ssize - 1;
1379 <        @SuppressWarnings("unchecked") Segment<K,V>[] segments = (Segment<K,V>[])
1379 >        @SuppressWarnings("unchecked")
1380 >        Segment<K,V>[] segments = (Segment<K,V>[])
1381              new Segment<?,?>[DEFAULT_CONCURRENCY_LEVEL];
1382          for (int i = 0; i < segments.length; ++i)
1383              segments[i] = new Segment<K,V>(LOAD_FACTOR);
1384 <        s.putFields().put("segments", segments);
1385 <        s.putFields().put("segmentShift", segmentShift);
1386 <        s.putFields().put("segmentMask", segmentMask);
1384 >        java.io.ObjectOutputStream.PutField streamFields = s.putFields();
1385 >        streamFields.put("segments", segments);
1386 >        streamFields.put("segmentShift", segmentShift);
1387 >        streamFields.put("segmentMask", segmentMask);
1388          s.writeFields();
1389  
1390          Node<K,V>[] t;
# Line 1360 | Line 1397 | public class ConcurrentHashMap<K,V> exte
1397          }
1398          s.writeObject(null);
1399          s.writeObject(null);
1363        segments = null; // throw away
1400      }
1401  
1402      /**
1403 <     * Reconstitutes the instance from a stream (that is, deserializes it).
1403 >     * Reconstitutes this map from a stream (that is, deserializes it).
1404       * @param s the stream
1405       * @throws ClassNotFoundException if the class of a serialized object
1406       *         could not be found
# Line 1384 | Line 1420 | public class ConcurrentHashMap<K,V> exte
1420          long size = 0L;
1421          Node<K,V> p = null;
1422          for (;;) {
1423 <            @SuppressWarnings("unchecked") K k = (K) s.readObject();
1424 <            @SuppressWarnings("unchecked") V v = (V) s.readObject();
1423 >            @SuppressWarnings("unchecked")
1424 >            K k = (K) s.readObject();
1425 >            @SuppressWarnings("unchecked")
1426 >            V v = (V) s.readObject();
1427              if (k != null && v != null) {
1428                  p = new Node<K,V>(spread(k.hashCode()), k, v, p);
1429                  ++size;
# Line 1396 | Line 1434 | public class ConcurrentHashMap<K,V> exte
1434          if (size == 0L)
1435              sizeCtl = 0;
1436          else {
1437 <            int n;
1438 <            if (size >= (long)(MAXIMUM_CAPACITY >>> 1))
1439 <                n = MAXIMUM_CAPACITY;
1440 <            else {
1441 <                int sz = (int)size;
1404 <                n = tableSizeFor(sz + (sz >>> 1) + 1);
1405 <            }
1406 <            @SuppressWarnings({"rawtypes","unchecked"})
1407 <                Node<K,V>[] tab = (Node<K,V>[])new Node[n];
1437 >            long ts = (long)(1.0 + size / LOAD_FACTOR);
1438 >            int n = (ts >= (long)MAXIMUM_CAPACITY) ?
1439 >                MAXIMUM_CAPACITY : tableSizeFor((int)ts);
1440 >            @SuppressWarnings("unchecked")
1441 >            Node<K,V>[] tab = (Node<K,V>[])new Node<?,?>[n];
1442              int mask = n - 1;
1443              long added = 0L;
1444              while (p != null) {
# Line 1562 | Line 1596 | public class ConcurrentHashMap<K,V> exte
1596      }
1597  
1598      /**
1599 +     * Helper method for EntrySetView.removeIf.
1600 +     */
1601 +    boolean removeEntryIf(Predicate<? super Entry<K,V>> function) {
1602 +        if (function == null) throw new NullPointerException();
1603 +        Node<K,V>[] t;
1604 +        boolean removed = false;
1605 +        if ((t = table) != null) {
1606 +            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1607 +            for (Node<K,V> p; (p = it.advance()) != null; ) {
1608 +                K k = p.key;
1609 +                V v = p.val;
1610 +                Map.Entry<K,V> e = new AbstractMap.SimpleImmutableEntry<>(k, v);
1611 +                if (function.test(e) && replaceNode(k, null, v) != null)
1612 +                    removed = true;
1613 +            }
1614 +        }
1615 +        return removed;
1616 +    }
1617 +
1618 +    /**
1619 +     * Helper method for ValuesView.removeIf.
1620 +     */
1621 +    boolean removeValueIf(Predicate<? super V> function) {
1622 +        if (function == null) throw new NullPointerException();
1623 +        Node<K,V>[] t;
1624 +        boolean removed = false;
1625 +        if ((t = table) != null) {
1626 +            Traverser<K,V> it = new Traverser<K,V>(t, t.length, 0, t.length);
1627 +            for (Node<K,V> p; (p = it.advance()) != null; ) {
1628 +                K k = p.key;
1629 +                V v = p.val;
1630 +                if (function.test(v) && replaceNode(k, null, v) != null)
1631 +                    removed = true;
1632 +            }
1633 +        }
1634 +        return removed;
1635 +    }
1636 +
1637 +    /**
1638       * If the specified key is not already associated with a value,
1639       * attempts to compute its value using the given mapping function
1640       * and enters it into this map unless {@code null}.  The entire
# Line 1590 | Line 1663 | public class ConcurrentHashMap<K,V> exte
1663          V val = null;
1664          int binCount = 0;
1665          for (Node<K,V>[] tab = table;;) {
1666 <            Node<K,V> f; int n, i, fh;
1666 >            Node<K,V> f; int n, i, fh; K fk; V fv;
1667              if (tab == null || (n = tab.length) == 0)
1668                  tab = initTable();
1669              else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
# Line 1601 | Line 1674 | public class ConcurrentHashMap<K,V> exte
1674                          Node<K,V> node = null;
1675                          try {
1676                              if ((val = mappingFunction.apply(key)) != null)
1677 <                                node = new Node<K,V>(h, key, val, null);
1677 >                                node = new Node<K,V>(h, key, val);
1678                          } finally {
1679                              setTabAt(tab, i, node);
1680                          }
# Line 1612 | Line 1685 | public class ConcurrentHashMap<K,V> exte
1685              }
1686              else if ((fh = f.hash) == MOVED)
1687                  tab = helpTransfer(tab, f);
1688 +            else if (fh == h    // check first node without acquiring lock
1689 +                     && ((fk = f.key) == key || (fk != null && key.equals(fk)))
1690 +                     && (fv = f.val) != null)
1691 +                return fv;
1692              else {
1693                  boolean added = false;
1694                  synchronized (f) {
# Line 1619 | Line 1696 | public class ConcurrentHashMap<K,V> exte
1696                          if (fh >= 0) {
1697                              binCount = 1;
1698                              for (Node<K,V> e = f;; ++binCount) {
1699 <                                K ek; V ev;
1699 >                                K ek;
1700                                  if (e.hash == h &&
1701                                      ((ek = e.key) == key ||
1702                                       (ek != null && key.equals(ek)))) {
# Line 1629 | Line 1706 | public class ConcurrentHashMap<K,V> exte
1706                                  Node<K,V> pred = e;
1707                                  if ((e = e.next) == null) {
1708                                      if ((val = mappingFunction.apply(key)) != null) {
1709 +                                        if (pred.next != null)
1710 +                                            throw new IllegalStateException("Recursive update");
1711                                          added = true;
1712 <                                        pred.next = new Node<K,V>(h, key, val, null);
1712 >                                        pred.next = new Node<K,V>(h, key, val);
1713                                      }
1714                                      break;
1715                                  }
# Line 1648 | Line 1727 | public class ConcurrentHashMap<K,V> exte
1727                                  t.putTreeVal(h, key, val);
1728                              }
1729                          }
1730 +                        else if (f instanceof ReservationNode)
1731 +                            throw new IllegalStateException("Recursive update");
1732                      }
1733                  }
1734                  if (binCount != 0) {
# Line 1743 | Line 1824 | public class ConcurrentHashMap<K,V> exte
1824                                  }
1825                              }
1826                          }
1827 +                        else if (f instanceof ReservationNode)
1828 +                            throw new IllegalStateException("Recursive update");
1829                      }
1830                  }
1831                  if (binCount != 0)
# Line 1795 | Line 1878 | public class ConcurrentHashMap<K,V> exte
1878                          try {
1879                              if ((val = remappingFunction.apply(key, null)) != null) {
1880                                  delta = 1;
1881 <                                node = new Node<K,V>(h, key, val, null);
1881 >                                node = new Node<K,V>(h, key, val);
1882                              }
1883                          } finally {
1884                              setTabAt(tab, i, node);
# Line 1834 | Line 1917 | public class ConcurrentHashMap<K,V> exte
1917                                  if ((e = e.next) == null) {
1918                                      val = remappingFunction.apply(key, null);
1919                                      if (val != null) {
1920 +                                        if (pred.next != null)
1921 +                                            throw new IllegalStateException("Recursive update");
1922                                          delta = 1;
1923 <                                        pred.next =
1839 <                                            new Node<K,V>(h, key, val, null);
1923 >                                        pred.next = new Node<K,V>(h, key, val);
1924                                      }
1925                                      break;
1926                                  }
# Line 1866 | Line 1950 | public class ConcurrentHashMap<K,V> exte
1950                                      setTabAt(tab, i, untreeify(t.first));
1951                              }
1952                          }
1953 +                        else if (f instanceof ReservationNode)
1954 +                            throw new IllegalStateException("Recursive update");
1955                      }
1956                  }
1957                  if (binCount != 0) {
# Line 1912 | Line 1998 | public class ConcurrentHashMap<K,V> exte
1998              if (tab == null || (n = tab.length) == 0)
1999                  tab = initTable();
2000              else if ((f = tabAt(tab, i = (n - 1) & h)) == null) {
2001 <                if (casTabAt(tab, i, null, new Node<K,V>(h, key, value, null))) {
2001 >                if (casTabAt(tab, i, null, new Node<K,V>(h, key, value))) {
2002                      delta = 1;
2003                      val = value;
2004                      break;
# Line 1947 | Line 2033 | public class ConcurrentHashMap<K,V> exte
2033                                  if ((e = e.next) == null) {
2034                                      delta = 1;
2035                                      val = value;
2036 <                                    pred.next =
1951 <                                        new Node<K,V>(h, key, val, null);
2036 >                                    pred.next = new Node<K,V>(h, key, val);
2037                                      break;
2038                                  }
2039                              }
# Line 1975 | Line 2060 | public class ConcurrentHashMap<K,V> exte
2060                                      setTabAt(tab, i, untreeify(t.first));
2061                              }
2062                          }
2063 +                        else if (f instanceof ReservationNode)
2064 +                            throw new IllegalStateException("Recursive update");
2065                      }
2066                  }
2067                  if (binCount != 0) {
# Line 1992 | Line 2079 | public class ConcurrentHashMap<K,V> exte
2079      // Hashtable legacy methods
2080  
2081      /**
2082 <     * Legacy method testing if some key maps into the specified value
2083 <     * in this table.  This method is identical in functionality to
2082 >     * Tests if some key maps into the specified value in this table.
2083 >     *
2084 >     * <p>Note that this method is identical in functionality to
2085       * {@link #containsValue(Object)}, and exists solely to ensure
2086       * full compatibility with class {@link java.util.Hashtable},
2087       * which supported this method prior to introduction of the
2088 <     * Java Collections framework.
2088 >     * Java Collections Framework.
2089       *
2090       * @param  value a value to search for
2091       * @return {@code true} if and only if some key maps to the
# Line 2006 | Line 2094 | public class ConcurrentHashMap<K,V> exte
2094       *         {@code false} otherwise
2095       * @throws NullPointerException if the specified value is null
2096       */
2097 <    @Deprecated public boolean contains(Object value) {
2097 >    public boolean contains(Object value) {
2098          return containsValue(value);
2099      }
2100  
# Line 2106 | Line 2194 | public class ConcurrentHashMap<K,V> exte
2194      static final class ForwardingNode<K,V> extends Node<K,V> {
2195          final Node<K,V>[] nextTable;
2196          ForwardingNode(Node<K,V>[] tab) {
2197 <            super(MOVED, null, null, null);
2197 >            super(MOVED, null, null);
2198              this.nextTable = tab;
2199          }
2200  
# Line 2138 | Line 2226 | public class ConcurrentHashMap<K,V> exte
2226      }
2227  
2228      /**
2229 <     * A place-holder node used in computeIfAbsent and compute
2229 >     * A place-holder node used in computeIfAbsent and compute.
2230       */
2231      static final class ReservationNode<K,V> extends Node<K,V> {
2232          ReservationNode() {
2233 <            super(RESERVED, null, null, null);
2233 >            super(RESERVED, null, null);
2234          }
2235  
2236          Node<K,V> find(int h, Object k) {
# Line 2153 | Line 2241 | public class ConcurrentHashMap<K,V> exte
2241      /* ---------------- Table Initialization and Resizing -------------- */
2242  
2243      /**
2244 +     * Returns the stamp bits for resizing a table of size n.
2245 +     * Must be negative when shifted left by RESIZE_STAMP_SHIFT.
2246 +     */
2247 +    static final int resizeStamp(int n) {
2248 +        return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
2249 +    }
2250 +
2251 +    /**
2252       * Initializes table, using the size recorded in sizeCtl.
2253       */
2254      private final Node<K,V>[] initTable() {
# Line 2160 | Line 2256 | public class ConcurrentHashMap<K,V> exte
2256          while ((tab = table) == null || tab.length == 0) {
2257              if ((sc = sizeCtl) < 0)
2258                  Thread.yield(); // lost initialization race; just spin
2259 <            else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
2259 >            else if (U.compareAndSetInt(this, SIZECTL, sc, -1)) {
2260                  try {
2261                      if ((tab = table) == null || tab.length == 0) {
2262                          int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
2263 <                        @SuppressWarnings({"rawtypes","unchecked"})
2264 <                            Node<K,V>[] nt = (Node<K,V>[])new Node[n];
2263 >                        @SuppressWarnings("unchecked")
2264 >                        Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2265                          table = tab = nt;
2266                          sc = n - (n >>> 2);
2267                      }
# Line 2189 | Line 2285 | public class ConcurrentHashMap<K,V> exte
2285       * @param check if <0, don't check resize, if <= 1 only check if uncontended
2286       */
2287      private final void addCount(long x, int check) {
2288 <        CounterCell[] as; long b, s;
2289 <        if ((as = counterCells) != null ||
2290 <            !U.compareAndSwapLong(this, BASECOUNT, b = baseCount, s = b + x)) {
2291 <            CounterCell a; long v; int m;
2288 >        CounterCell[] cs; long b, s;
2289 >        if ((cs = counterCells) != null ||
2290 >            !U.compareAndSetLong(this, BASECOUNT, b = baseCount, s = b + x)) {
2291 >            CounterCell c; long v; int m;
2292              boolean uncontended = true;
2293 <            if (as == null || (m = as.length - 1) < 0 ||
2294 <                (a = as[ThreadLocalRandom.getProbe() & m]) == null ||
2293 >            if (cs == null || (m = cs.length - 1) < 0 ||
2294 >                (c = cs[ThreadLocalRandom.getProbe() & m]) == null ||
2295                  !(uncontended =
2296 <                  U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) {
2296 >                  U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))) {
2297                  fullAddCount(x, uncontended);
2298                  return;
2299              }
# Line 2206 | Line 2302 | public class ConcurrentHashMap<K,V> exte
2302              s = sumCount();
2303          }
2304          if (check >= 0) {
2305 <            Node<K,V>[] tab, nt; int sc;
2305 >            Node<K,V>[] tab, nt; int n, sc;
2306              while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
2307 <                   tab.length < MAXIMUM_CAPACITY) {
2307 >                   (n = tab.length) < MAXIMUM_CAPACITY) {
2308 >                int rs = resizeStamp(n) << RESIZE_STAMP_SHIFT;
2309                  if (sc < 0) {
2310 <                    if (sc == -1 || transferIndex <= transferOrigin ||
2311 <                        (nt = nextTable) == null)
2310 >                    if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
2311 >                        (nt = nextTable) == null || transferIndex <= 0)
2312                          break;
2313 <                    if (U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
2313 >                    if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
2314                          transfer(tab, nt);
2315                  }
2316 <                else if (U.compareAndSwapInt(this, SIZECTL, sc, -2))
2316 >                else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
2317                      transfer(tab, null);
2318                  s = sumCount();
2319              }
# Line 2228 | Line 2325 | public class ConcurrentHashMap<K,V> exte
2325       */
2326      final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
2327          Node<K,V>[] nextTab; int sc;
2328 <        if ((f instanceof ForwardingNode) &&
2328 >        if (tab != null && (f instanceof ForwardingNode) &&
2329              (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
2330 <            if (nextTab == nextTable && tab == table &&
2331 <                transferIndex > transferOrigin && (sc = sizeCtl) < -1 &&
2332 <                U.compareAndSwapInt(this, SIZECTL, sc, sc - 1))
2333 <                transfer(tab, nextTab);
2330 >            int rs = resizeStamp(tab.length) << RESIZE_STAMP_SHIFT;
2331 >            while (nextTab == nextTable && table == tab &&
2332 >                   (sc = sizeCtl) < 0) {
2333 >                if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
2334 >                    transferIndex <= 0)
2335 >                    break;
2336 >                if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1)) {
2337 >                    transfer(tab, nextTab);
2338 >                    break;
2339 >                }
2340 >            }
2341              return nextTab;
2342          }
2343          return table;
# Line 2252 | Line 2356 | public class ConcurrentHashMap<K,V> exte
2356              Node<K,V>[] tab = table; int n;
2357              if (tab == null || (n = tab.length) == 0) {
2358                  n = (sc > c) ? sc : c;
2359 <                if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {
2359 >                if (U.compareAndSetInt(this, SIZECTL, sc, -1)) {
2360                      try {
2361                          if (table == tab) {
2362 <                            @SuppressWarnings({"rawtypes","unchecked"})
2363 <                                Node<K,V>[] nt = (Node<K,V>[])new Node[n];
2362 >                            @SuppressWarnings("unchecked")
2363 >                            Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
2364                              table = nt;
2365                              sc = n - (n >>> 2);
2366                          }
# Line 2267 | Line 2371 | public class ConcurrentHashMap<K,V> exte
2371              }
2372              else if (c <= sc || n >= MAXIMUM_CAPACITY)
2373                  break;
2374 <            else if (tab == table &&
2375 <                     U.compareAndSwapInt(this, SIZECTL, sc, -2))
2376 <                transfer(tab, null);
2374 >            else if (tab == table) {
2375 >                int rs = resizeStamp(n);
2376 >                if (U.compareAndSetInt(this, SIZECTL, sc,
2377 >                                        (rs << RESIZE_STAMP_SHIFT) + 2))
2378 >                    transfer(tab, null);
2379 >            }
2380          }
2381      }
2382  
# Line 2283 | Line 2390 | public class ConcurrentHashMap<K,V> exte
2390              stride = MIN_TRANSFER_STRIDE; // subdivide range
2391          if (nextTab == null) {            // initiating
2392              try {
2393 <                @SuppressWarnings({"rawtypes","unchecked"})
2394 <                    Node<K,V>[] nt = (Node<K,V>[])new Node[n << 1];
2393 >                @SuppressWarnings("unchecked")
2394 >                Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
2395                  nextTab = nt;
2396              } catch (Throwable ex) {      // try to cope with OOME
2397                  sizeCtl = Integer.MAX_VALUE;
2398                  return;
2399              }
2400              nextTable = nextTab;
2294            transferOrigin = n;
2401              transferIndex = n;
2296            ForwardingNode<K,V> rev = new ForwardingNode<K,V>(tab);
2297            for (int k = n; k > 0;) {    // progressively reveal ready slots
2298                int nextk = (k > stride) ? k - stride : 0;
2299                for (int m = nextk; m < k; ++m)
2300                    nextTab[m] = rev;
2301                for (int m = n + nextk; m < n + k; ++m)
2302                    nextTab[m] = rev;
2303                U.putOrderedInt(this, TRANSFERORIGIN, k = nextk);
2304            }
2402          }
2403          int nextn = nextTab.length;
2404          ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);
2405          boolean advance = true;
2406          boolean finishing = false; // to ensure sweep before committing nextTab
2407          for (int i = 0, bound = 0;;) {
2408 <            int nextIndex, nextBound, fh; Node<K,V> f;
2408 >            Node<K,V> f; int fh;
2409              while (advance) {
2410 +                int nextIndex, nextBound;
2411                  if (--i >= bound || finishing)
2412                      advance = false;
2413 <                else if ((nextIndex = transferIndex) <= transferOrigin) {
2413 >                else if ((nextIndex = transferIndex) <= 0) {
2414                      i = -1;
2415                      advance = false;
2416                  }
2417 <                else if (U.compareAndSwapInt
2417 >                else if (U.compareAndSetInt
2418                           (this, TRANSFERINDEX, nextIndex,
2419                            nextBound = (nextIndex > stride ?
2420                                         nextIndex - stride : 0))) {
# Line 2326 | Line 2424 | public class ConcurrentHashMap<K,V> exte
2424                  }
2425              }
2426              if (i < 0 || i >= n || i + n >= nextn) {
2427 +                int sc;
2428                  if (finishing) {
2429                      nextTable = null;
2430                      table = nextTab;
2431                      sizeCtl = (n << 1) - (n >>> 1);
2432                      return;
2433                  }
2434 <                for (int sc;;) {
2435 <                    if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, ++sc)) {
2436 <                        if (sc != -1)
2437 <                            return;
2438 <                        finishing = advance = true;
2340 <                        i = n; // recheck before commit
2341 <                        break;
2342 <                    }
2343 <                }
2344 <            }
2345 <            else if ((f = tabAt(tab, i)) == null) {
2346 <                if (casTabAt(tab, i, null, fwd)) {
2347 <                    setTabAt(nextTab, i, null);
2348 <                    setTabAt(nextTab, i + n, null);
2349 <                    advance = true;
2434 >                if (U.compareAndSetInt(this, SIZECTL, sc = sizeCtl, sc - 1)) {
2435 >                    if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT)
2436 >                        return;
2437 >                    finishing = advance = true;
2438 >                    i = n; // recheck before commit
2439                  }
2440              }
2441 +            else if ((f = tabAt(tab, i)) == null)
2442 +                advance = casTabAt(tab, i, null, fwd);
2443              else if ((fh = f.hash) == MOVED)
2444                  advance = true; // already processed
2445              else {
# Line 2420 | Line 2511 | public class ConcurrentHashMap<K,V> exte
2511                              setTabAt(tab, i, fwd);
2512                              advance = true;
2513                          }
2514 +                        else if (f instanceof ReservationNode)
2515 +                            throw new IllegalStateException("Recursive update");
2516                      }
2517                  }
2518              }
# Line 2432 | Line 2525 | public class ConcurrentHashMap<K,V> exte
2525       * A padded cell for distributing counts.  Adapted from LongAdder
2526       * and Striped64.  See their internal docs for explanation.
2527       */
2528 <    @sun.misc.Contended static final class CounterCell {
2528 >    @jdk.internal.vm.annotation.Contended static final class CounterCell {
2529          volatile long value;
2530          CounterCell(long x) { value = x; }
2531      }
2532  
2533      final long sumCount() {
2534 <        CounterCell[] as = counterCells; CounterCell a;
2534 >        CounterCell[] cs = counterCells;
2535          long sum = baseCount;
2536 <        if (as != null) {
2537 <            for (int i = 0; i < as.length; ++i) {
2538 <                if ((a = as[i]) != null)
2539 <                    sum += a.value;
2447 <            }
2536 >        if (cs != null) {
2537 >            for (CounterCell c : cs)
2538 >                if (c != null)
2539 >                    sum += c.value;
2540          }
2541          return sum;
2542      }
# Line 2459 | Line 2551 | public class ConcurrentHashMap<K,V> exte
2551          }
2552          boolean collide = false;                // True if last slot nonempty
2553          for (;;) {
2554 <            CounterCell[] as; CounterCell a; int n; long v;
2555 <            if ((as = counterCells) != null && (n = as.length) > 0) {
2556 <                if ((a = as[(n - 1) & h]) == null) {
2554 >            CounterCell[] cs; CounterCell c; int n; long v;
2555 >            if ((cs = counterCells) != null && (n = cs.length) > 0) {
2556 >                if ((c = cs[(n - 1) & h]) == null) {
2557                      if (cellsBusy == 0) {            // Try to attach new Cell
2558                          CounterCell r = new CounterCell(x); // Optimistic create
2559                          if (cellsBusy == 0 &&
2560 <                            U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
2560 >                            U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
2561                              boolean created = false;
2562                              try {               // Recheck under lock
2563                                  CounterCell[] rs; int m, j;
# Line 2487 | Line 2579 | public class ConcurrentHashMap<K,V> exte
2579                  }
2580                  else if (!wasUncontended)       // CAS already known to fail
2581                      wasUncontended = true;      // Continue after rehash
2582 <                else if (U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))
2582 >                else if (U.compareAndSetLong(c, CELLVALUE, v = c.value, v + x))
2583                      break;
2584 <                else if (counterCells != as || n >= NCPU)
2584 >                else if (counterCells != cs || n >= NCPU)
2585                      collide = false;            // At max size or stale
2586                  else if (!collide)
2587                      collide = true;
2588                  else if (cellsBusy == 0 &&
2589 <                         U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
2589 >                         U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
2590                      try {
2591 <                        if (counterCells == as) {// Expand table unless stale
2592 <                            CounterCell[] rs = new CounterCell[n << 1];
2501 <                            for (int i = 0; i < n; ++i)
2502 <                                rs[i] = as[i];
2503 <                            counterCells = rs;
2504 <                        }
2591 >                        if (counterCells == cs) // Expand table unless stale
2592 >                            counterCells = Arrays.copyOf(cs, n << 1);
2593                      } finally {
2594                          cellsBusy = 0;
2595                      }
# Line 2510 | Line 2598 | public class ConcurrentHashMap<K,V> exte
2598                  }
2599                  h = ThreadLocalRandom.advanceProbe(h);
2600              }
2601 <            else if (cellsBusy == 0 && counterCells == as &&
2602 <                     U.compareAndSwapInt(this, CELLSBUSY, 0, 1)) {
2601 >            else if (cellsBusy == 0 && counterCells == cs &&
2602 >                     U.compareAndSetInt(this, CELLSBUSY, 0, 1)) {
2603                  boolean init = false;
2604                  try {                           // Initialize table
2605 <                    if (counterCells == as) {
2605 >                    if (counterCells == cs) {
2606                          CounterCell[] rs = new CounterCell[2];
2607                          rs[h & 1] = new CounterCell(x);
2608                          counterCells = rs;
# Line 2526 | Line 2614 | public class ConcurrentHashMap<K,V> exte
2614                  if (init)
2615                      break;
2616              }
2617 <            else if (U.compareAndSwapLong(this, BASECOUNT, v = baseCount, v + x))
2617 >            else if (U.compareAndSetLong(this, BASECOUNT, v = baseCount, v + x))
2618                  break;                          // Fall back on using base
2619          }
2620      }
# Line 2538 | Line 2626 | public class ConcurrentHashMap<K,V> exte
2626       * too small, in which case resizes instead.
2627       */
2628      private final void treeifyBin(Node<K,V>[] tab, int index) {
2629 <        Node<K,V> b; int n, sc;
2629 >        Node<K,V> b; int n;
2630          if (tab != null) {
2631 <            if ((n = tab.length) < MIN_TREEIFY_CAPACITY) {
2632 <                if (tab == table && (sc = sizeCtl) >= 0 &&
2545 <                    U.compareAndSwapInt(this, SIZECTL, sc, -2))
2546 <                    transfer(tab, null);
2547 <            }
2631 >            if ((n = tab.length) < MIN_TREEIFY_CAPACITY)
2632 >                tryPresize(n << 1);
2633              else if ((b = tabAt(tab, index)) != null && b.hash >= 0) {
2634                  synchronized (b) {
2635                      if (tabAt(tab, index) == b) {
# Line 2567 | Line 2652 | public class ConcurrentHashMap<K,V> exte
2652      }
2653  
2654      /**
2655 <     * Returns a list on non-TreeNodes replacing those in given list.
2655 >     * Returns a list of non-TreeNodes replacing those in given list.
2656       */
2657      static <K,V> Node<K,V> untreeify(Node<K,V> b) {
2658          Node<K,V> hd = null, tl = null;
2659          for (Node<K,V> q = b; q != null; q = q.next) {
2660 <            Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val, null);
2660 >            Node<K,V> p = new Node<K,V>(q.hash, q.key, q.val);
2661              if (tl == null)
2662                  hd = p;
2663              else
# Line 2585 | Line 2670 | public class ConcurrentHashMap<K,V> exte
2670      /* ---------------- TreeNodes -------------- */
2671  
2672      /**
2673 <     * Nodes for use in TreeBins
2673 >     * Nodes for use in TreeBins.
2674       */
2675      static final class TreeNode<K,V> extends Node<K,V> {
2676          TreeNode<K,V> parent;  // red-black tree links
# Line 2611 | Line 2696 | public class ConcurrentHashMap<K,V> exte
2696          final TreeNode<K,V> findTreeNode(int h, Object k, Class<?> kc) {
2697              if (k != null) {
2698                  TreeNode<K,V> p = this;
2699 <                do  {
2699 >                do {
2700                      int ph, dir; K pk; TreeNode<K,V> q;
2701                      TreeNode<K,V> pl = p.left, pr = p.right;
2702                      if ((ph = p.hash) > h)
# Line 2620 | Line 2705 | public class ConcurrentHashMap<K,V> exte
2705                          p = pr;
2706                      else if ((pk = p.key) == k || (pk != null && k.equals(pk)))
2707                          return p;
2708 <                    else if (pl == null && pr == null)
2709 <                        break;
2708 >                    else if (pl == null)
2709 >                        p = pr;
2710 >                    else if (pr == null)
2711 >                        p = pl;
2712                      else if ((kc != null ||
2713                                (kc = comparableClassFor(k)) != null) &&
2714                               (dir = compareComparables(kc, k, pk)) != 0)
2715                          p = (dir < 0) ? pl : pr;
2716 <                    else if (pl == null)
2630 <                        p = pr;
2631 <                    else if (pr == null ||
2632 <                             (q = pr.findTreeNode(h, k, kc)) == null)
2633 <                        p = pl;
2634 <                    else
2716 >                    else if ((q = pr.findTreeNode(h, k, kc)) != null)
2717                          return q;
2718 +                    else
2719 +                        p = pl;
2720                  } while (p != null);
2721              }
2722              return null;
# Line 2659 | Line 2743 | public class ConcurrentHashMap<K,V> exte
2743          static final int READER = 4; // increment value for setting read lock
2744  
2745          /**
2746 +         * Tie-breaking utility for ordering insertions when equal
2747 +         * hashCodes and non-comparable. We don't require a total
2748 +         * order, just a consistent insertion rule to maintain
2749 +         * equivalence across rebalancings. Tie-breaking further than
2750 +         * necessary simplifies testing a bit.
2751 +         */
2752 +        static int tieBreakOrder(Object a, Object b) {
2753 +            int d;
2754 +            if (a == null || b == null ||
2755 +                (d = a.getClass().getName().
2756 +                 compareTo(b.getClass().getName())) == 0)
2757 +                d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
2758 +                     -1 : 1);
2759 +            return d;
2760 +        }
2761 +
2762 +        /**
2763           * Creates bin with initial set of nodes headed by b.
2764           */
2765          TreeBin(TreeNode<K,V> b) {
2766 <            super(TREEBIN, null, null, null);
2766 >            super(TREEBIN, null, null);
2767              this.first = b;
2768              TreeNode<K,V> r = null;
2769              for (TreeNode<K,V> x = b, next; x != null; x = next) {
# Line 2674 | Line 2775 | public class ConcurrentHashMap<K,V> exte
2775                      r = x;
2776                  }
2777                  else {
2778 <                    Object key = x.key;
2779 <                    int hash = x.hash;
2778 >                    K k = x.key;
2779 >                    int h = x.hash;
2780                      Class<?> kc = null;
2781                      for (TreeNode<K,V> p = r;;) {
2782                          int dir, ph;
2783 <                        if ((ph = p.hash) > hash)
2783 >                        K pk = p.key;
2784 >                        if ((ph = p.hash) > h)
2785                              dir = -1;
2786 <                        else if (ph < hash)
2786 >                        else if (ph < h)
2787                              dir = 1;
2788 <                        else if ((kc != null ||
2789 <                                  (kc = comparableClassFor(key)) != null))
2790 <                            dir = compareComparables(kc, key, p.key);
2791 <                        else
2690 <                            dir = 0;
2788 >                        else if ((kc == null &&
2789 >                                  (kc = comparableClassFor(k)) == null) ||
2790 >                                 (dir = compareComparables(kc, k, pk)) == 0)
2791 >                            dir = tieBreakOrder(k, pk);
2792                          TreeNode<K,V> xp = p;
2793                          if ((p = (dir <= 0) ? p.left : p.right) == null) {
2794                              x.parent = xp;
# Line 2702 | Line 2803 | public class ConcurrentHashMap<K,V> exte
2803                  }
2804              }
2805              this.root = r;
2806 +            assert checkInvariants(root);
2807          }
2808  
2809          /**
2810           * Acquires write lock for tree restructuring.
2811           */
2812          private final void lockRoot() {
2813 <            if (!U.compareAndSwapInt(this, LOCKSTATE, 0, WRITER))
2813 >            if (!U.compareAndSetInt(this, LOCKSTATE, 0, WRITER))
2814                  contendedLock(); // offload to separate method
2815          }
2816  
# Line 2725 | Line 2827 | public class ConcurrentHashMap<K,V> exte
2827          private final void contendedLock() {
2828              boolean waiting = false;
2829              for (int s;;) {
2830 <                if (((s = lockState) & WRITER) == 0) {
2831 <                    if (U.compareAndSwapInt(this, LOCKSTATE, s, WRITER)) {
2830 >                if (((s = lockState) & ~WAITER) == 0) {
2831 >                    if (U.compareAndSetInt(this, LOCKSTATE, s, WRITER)) {
2832                          if (waiting)
2833                              waiter = null;
2834                          return;
2835                      }
2836                  }
2837 <                else if ((s | WAITER) == 0) {
2838 <                    if (U.compareAndSwapInt(this, LOCKSTATE, s, s | WAITER)) {
2837 >                else if ((s & WAITER) == 0) {
2838 >                    if (U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER)) {
2839                          waiting = true;
2840                          waiter = Thread.currentThread();
2841                      }
# Line 2750 | Line 2852 | public class ConcurrentHashMap<K,V> exte
2852           */
2853          final Node<K,V> find(int h, Object k) {
2854              if (k != null) {
2855 <                for (Node<K,V> e = first; e != null; e = e.next) {
2855 >                for (Node<K,V> e = first; e != null; ) {
2856                      int s; K ek;
2857                      if (((s = lockState) & (WAITER|WRITER)) != 0) {
2858                          if (e.hash == h &&
2859                              ((ek = e.key) == k || (ek != null && k.equals(ek))))
2860                              return e;
2861 +                        e = e.next;
2862                      }
2863 <                    else if (U.compareAndSwapInt(this, LOCKSTATE, s,
2863 >                    else if (U.compareAndSetInt(this, LOCKSTATE, s,
2864                                                   s + READER)) {
2865                          TreeNode<K,V> r, p;
2866                          try {
# Line 2782 | Line 2885 | public class ConcurrentHashMap<K,V> exte
2885           */
2886          final TreeNode<K,V> putTreeVal(int h, K k, V v) {
2887              Class<?> kc = null;
2888 +            boolean searched = false;
2889              for (TreeNode<K,V> p = root;;) {
2890 <                int dir, ph; K pk; TreeNode<K,V> q, pr;
2890 >                int dir, ph; K pk;
2891                  if (p == null) {
2892                      first = root = new TreeNode<K,V>(h, k, v, null, null);
2893                      break;
# Line 2797 | Line 2901 | public class ConcurrentHashMap<K,V> exte
2901                  else if ((kc == null &&
2902                            (kc = comparableClassFor(k)) == null) ||
2903                           (dir = compareComparables(kc, k, pk)) == 0) {
2904 <                    if (p.left == null)
2905 <                        dir = 1;
2906 <                    else if ((pr = p.right) == null ||
2907 <                             (q = pr.findTreeNode(h, k, kc)) == null)
2908 <                        dir = -1;
2909 <                    else
2910 <                        return q;
2904 >                    if (!searched) {
2905 >                        TreeNode<K,V> q, ch;
2906 >                        searched = true;
2907 >                        if (((ch = p.left) != null &&
2908 >                             (q = ch.findTreeNode(h, k, kc)) != null) ||
2909 >                            ((ch = p.right) != null &&
2910 >                             (q = ch.findTreeNode(h, k, kc)) != null))
2911 >                            return q;
2912 >                    }
2913 >                    dir = tieBreakOrder(k, pk);
2914                  }
2915 +
2916                  TreeNode<K,V> xp = p;
2917 <                if ((p = (dir < 0) ? p.left : p.right) == null) {
2917 >                if ((p = (dir <= 0) ? p.left : p.right) == null) {
2918                      TreeNode<K,V> x, f = first;
2919                      first = x = new TreeNode<K,V>(h, k, v, f, xp);
2920                      if (f != null)
2921                          f.prev = x;
2922 <                    if (dir < 0)
2922 >                    if (dir <= 0)
2923                          xp.left = x;
2924                      else
2925                          xp.right = x;
# Line 3034 | Line 3142 | public class ConcurrentHashMap<K,V> exte
3142  
3143          static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
3144                                                     TreeNode<K,V> x) {
3145 <            for (TreeNode<K,V> xp, xpl, xpr;;)  {
3145 >            for (TreeNode<K,V> xp, xpl, xpr;;) {
3146                  if (x == null || x == root)
3147                      return root;
3148                  else if ((xp = x.parent) == null) {
# Line 3125 | Line 3233 | public class ConcurrentHashMap<K,V> exte
3233          }
3234  
3235          /**
3236 <         * Recursive invariant check
3236 >         * Checks invariants recursively for the tree of Nodes rooted at t.
3237           */
3238          static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
3239              TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
# Line 3149 | Line 3257 | public class ConcurrentHashMap<K,V> exte
3257              return true;
3258          }
3259  
3260 <        private static final sun.misc.Unsafe U;
3261 <        private static final long LOCKSTATE;
3262 <        static {
3155 <            try {
3156 <                U = sun.misc.Unsafe.getUnsafe();
3157 <                Class<?> k = TreeBin.class;
3158 <                LOCKSTATE = U.objectFieldOffset
3159 <                    (k.getDeclaredField("lockState"));
3160 <            } catch (Exception e) {
3161 <                throw new Error(e);
3162 <            }
3163 <        }
3260 >        private static final Unsafe U = Unsafe.getUnsafe();
3261 >        private static final long LOCKSTATE
3262 >                = U.objectFieldOffset(TreeBin.class, "lockState");
3263      }
3264  
3265      /* ----------------Table Traversal -------------- */
3266  
3267      /**
3268 +     * Records the table, its length, and current traversal index for a
3269 +     * traverser that must process a region of a forwarded table before
3270 +     * proceeding with current table.
3271 +     */
3272 +    static final class TableStack<K,V> {
3273 +        int length;
3274 +        int index;
3275 +        Node<K,V>[] tab;
3276 +        TableStack<K,V> next;
3277 +    }
3278 +
3279 +    /**
3280       * Encapsulates traversal for methods such as containsValue; also
3281       * serves as a base class for other iterators and spliterators.
3282       *
# Line 3189 | Line 3300 | public class ConcurrentHashMap<K,V> exte
3300      static class Traverser<K,V> {
3301          Node<K,V>[] tab;        // current table; updated if resized
3302          Node<K,V> next;         // the next entry to use
3303 +        TableStack<K,V> stack, spare; // to save/restore on ForwardingNodes
3304          int index;              // index of bin to use next
3305          int baseIndex;          // current index of initial table
3306          int baseLimit;          // index bound for initial table
# Line 3210 | Line 3322 | public class ConcurrentHashMap<K,V> exte
3322              if ((e = next) != null)
3323                  e = e.next;
3324              for (;;) {
3325 <                Node<K,V>[] t; int i, n; K ek;  // must use locals in checks
3325 >                Node<K,V>[] t; int i, n;  // must use locals in checks
3326                  if (e != null)
3327                      return next = e;
3328                  if (baseIndex >= baseLimit || (t = tab) == null ||
3329                      (n = t.length) <= (i = index) || i < 0)
3330                      return next = null;
3331 <                if ((e = tabAt(t, index)) != null && e.hash < 0) {
3331 >                if ((e = tabAt(t, i)) != null && e.hash < 0) {
3332                      if (e instanceof ForwardingNode) {
3333                          tab = ((ForwardingNode<K,V>)e).nextTable;
3334                          e = null;
3335 +                        pushState(t, i, n);
3336                          continue;
3337                      }
3338                      else if (e instanceof TreeBin)
# Line 3227 | Line 3340 | public class ConcurrentHashMap<K,V> exte
3340                      else
3341                          e = null;
3342                  }
3343 <                if ((index += baseSize) >= n)
3344 <                    index = ++baseIndex;    // visit upper slots if present
3343 >                if (stack != null)
3344 >                    recoverState(n);
3345 >                else if ((index = i + baseSize) >= n)
3346 >                    index = ++baseIndex; // visit upper slots if present
3347              }
3348          }
3349 +
3350 +        /**
3351 +         * Saves traversal state upon encountering a forwarding node.
3352 +         */
3353 +        private void pushState(Node<K,V>[] t, int i, int n) {
3354 +            TableStack<K,V> s = spare;  // reuse if possible
3355 +            if (s != null)
3356 +                spare = s.next;
3357 +            else
3358 +                s = new TableStack<K,V>();
3359 +            s.tab = t;
3360 +            s.length = n;
3361 +            s.index = i;
3362 +            s.next = stack;
3363 +            stack = s;
3364 +        }
3365 +
3366 +        /**
3367 +         * Possibly pops traversal state.
3368 +         *
3369 +         * @param n length of current table
3370 +         */
3371 +        private void recoverState(int n) {
3372 +            TableStack<K,V> s; int len;
3373 +            while ((s = stack) != null && (index += (len = s.length)) >= n) {
3374 +                n = len;
3375 +                index = s.index;
3376 +                tab = s.tab;
3377 +                s.tab = null;
3378 +                TableStack<K,V> next = s.next;
3379 +                s.next = spare; // save for reuse
3380 +                stack = next;
3381 +                spare = s;
3382 +            }
3383 +            if (s == null && (index += baseSize) >= n)
3384 +                index = ++baseIndex;
3385 +        }
3386      }
3387  
3388      /**
# Line 3261 | Line 3413 | public class ConcurrentHashMap<K,V> exte
3413  
3414      static final class KeyIterator<K,V> extends BaseIterator<K,V>
3415          implements Iterator<K>, Enumeration<K> {
3416 <        KeyIterator(Node<K,V>[] tab, int index, int size, int limit,
3416 >        KeyIterator(Node<K,V>[] tab, int size, int index, int limit,
3417                      ConcurrentHashMap<K,V> map) {
3418 <            super(tab, index, size, limit, map);
3418 >            super(tab, size, index, limit, map);
3419          }
3420  
3421          public final K next() {
# Line 3281 | Line 3433 | public class ConcurrentHashMap<K,V> exte
3433  
3434      static final class ValueIterator<K,V> extends BaseIterator<K,V>
3435          implements Iterator<V>, Enumeration<V> {
3436 <        ValueIterator(Node<K,V>[] tab, int index, int size, int limit,
3436 >        ValueIterator(Node<K,V>[] tab, int size, int index, int limit,
3437                        ConcurrentHashMap<K,V> map) {
3438 <            super(tab, index, size, limit, map);
3438 >            super(tab, size, index, limit, map);
3439          }
3440  
3441          public final V next() {
# Line 3301 | Line 3453 | public class ConcurrentHashMap<K,V> exte
3453  
3454      static final class EntryIterator<K,V> extends BaseIterator<K,V>
3455          implements Iterator<Map.Entry<K,V>> {
3456 <        EntryIterator(Node<K,V>[] tab, int index, int size, int limit,
3456 >        EntryIterator(Node<K,V>[] tab, int size, int index, int limit,
3457                        ConcurrentHashMap<K,V> map) {
3458 <            super(tab, index, size, limit, map);
3458 >            super(tab, size, index, limit, map);
3459          }
3460  
3461          public final Map.Entry<K,V> next() {
# Line 3319 | Line 3471 | public class ConcurrentHashMap<K,V> exte
3471      }
3472  
3473      /**
3474 <     * Exported Entry for EntryIterator
3474 >     * Exported Entry for EntryIterator.
3475       */
3476      static final class MapEntry<K,V> implements Map.Entry<K,V> {
3477          final K key; // non-null
# Line 3333 | Line 3485 | public class ConcurrentHashMap<K,V> exte
3485          public K getKey()        { return key; }
3486          public V getValue()      { return val; }
3487          public int hashCode()    { return key.hashCode() ^ val.hashCode(); }
3488 <        public String toString() { return key + "=" + val; }
3488 >        public String toString() {
3489 >            return Helpers.mapEntryToString(key, val);
3490 >        }
3491  
3492          public boolean equals(Object o) {
3493              Object k, v; Map.Entry<?,?> e;
# Line 3370 | Line 3524 | public class ConcurrentHashMap<K,V> exte
3524              this.est = est;
3525          }
3526  
3527 <        public Spliterator<K> trySplit() {
3527 >        public KeySpliterator<K,V> trySplit() {
3528              int i, f, h;
3529              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3530                  new KeySpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 3409 | Line 3563 | public class ConcurrentHashMap<K,V> exte
3563              this.est = est;
3564          }
3565  
3566 <        public Spliterator<V> trySplit() {
3566 >        public ValueSpliterator<K,V> trySplit() {
3567              int i, f, h;
3568              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3569                  new ValueSpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 3449 | Line 3603 | public class ConcurrentHashMap<K,V> exte
3603              this.est = est;
3604          }
3605  
3606 <        public Spliterator<Map.Entry<K,V>> trySplit() {
3606 >        public EntrySpliterator<K,V> trySplit() {
3607              int i, f, h;
3608              return (h = ((i = baseIndex) + (f = baseLimit)) >>> 1) <= i ? null :
3609                  new EntrySpliterator<K,V>(tab, baseSize, baseLimit = h,
# Line 4250 | Line 4404 | public class ConcurrentHashMap<K,V> exte
4404          // implementations below rely on concrete classes supplying these
4405          // abstract methods
4406          /**
4407 <         * Returns a "weakly consistent" iterator that will never
4408 <         * throw {@link ConcurrentModificationException}, and
4409 <         * guarantees to traverse elements as they existed upon
4410 <         * construction of the iterator, and may (but is not
4411 <         * guaranteed to) reflect any modifications subsequent to
4412 <         * construction.
4407 >         * Returns an iterator over the elements in this collection.
4408 >         *
4409 >         * <p>The returned iterator is
4410 >         * <a href="package-summary.html#Weakly"><i>weakly consistent</i></a>.
4411 >         *
4412 >         * @return an iterator over the elements in this collection
4413           */
4414          public abstract Iterator<E> iterator();
4415          public abstract boolean contains(Object o);
4416          public abstract boolean remove(Object o);
4417  
4418 <        private static final String oomeMsg = "Required array size too large";
4418 >        private static final String OOME_MSG = "Required array size too large";
4419  
4420          public final Object[] toArray() {
4421              long sz = map.mappingCount();
4422              if (sz > MAX_ARRAY_SIZE)
4423 <                throw new OutOfMemoryError(oomeMsg);
4423 >                throw new OutOfMemoryError(OOME_MSG);
4424              int n = (int)sz;
4425              Object[] r = new Object[n];
4426              int i = 0;
4427              for (E e : this) {
4428                  if (i == n) {
4429                      if (n >= MAX_ARRAY_SIZE)
4430 <                        throw new OutOfMemoryError(oomeMsg);
4430 >                        throw new OutOfMemoryError(OOME_MSG);
4431                      if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4432                          n = MAX_ARRAY_SIZE;
4433                      else
# Line 4289 | Line 4443 | public class ConcurrentHashMap<K,V> exte
4443          public final <T> T[] toArray(T[] a) {
4444              long sz = map.mappingCount();
4445              if (sz > MAX_ARRAY_SIZE)
4446 <                throw new OutOfMemoryError(oomeMsg);
4446 >                throw new OutOfMemoryError(OOME_MSG);
4447              int m = (int)sz;
4448              T[] r = (a.length >= m) ? a :
4449                  (T[])java.lang.reflect.Array
# Line 4299 | Line 4453 | public class ConcurrentHashMap<K,V> exte
4453              for (E e : this) {
4454                  if (i == n) {
4455                      if (n >= MAX_ARRAY_SIZE)
4456 <                        throw new OutOfMemoryError(oomeMsg);
4456 >                        throw new OutOfMemoryError(OOME_MSG);
4457                      if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1)
4458                          n = MAX_ARRAY_SIZE;
4459                      else
# Line 4352 | Line 4506 | public class ConcurrentHashMap<K,V> exte
4506              return true;
4507          }
4508  
4509 <        public final boolean removeAll(Collection<?> c) {
4509 >        public boolean removeAll(Collection<?> c) {
4510 >            if (c == null) throw new NullPointerException();
4511              boolean modified = false;
4512 <            for (Iterator<E> it = iterator(); it.hasNext();) {
4513 <                if (c.contains(it.next())) {
4514 <                    it.remove();
4515 <                    modified = true;
4512 >            // Use (c instanceof Set) as a hint that lookup in c is as
4513 >            // efficient as this view
4514 >            Node<K,V>[] t;
4515 >            if ((t = map.table) == null) {
4516 >                return false;
4517 >            } else if (c instanceof Set<?> && c.size() > t.length) {
4518 >                for (Iterator<?> it = iterator(); it.hasNext(); ) {
4519 >                    if (c.contains(it.next())) {
4520 >                        it.remove();
4521 >                        modified = true;
4522 >                    }
4523                  }
4524 +            } else {
4525 +                for (Object e : c)
4526 +                    modified |= remove(e);
4527              }
4528              return modified;
4529          }
4530  
4531          public final boolean retainAll(Collection<?> c) {
4532 +            if (c == null) throw new NullPointerException();
4533              boolean modified = false;
4534              for (Iterator<E> it = iterator(); it.hasNext();) {
4535                  if (!c.contains(it.next())) {
# Line 4544 | Line 4710 | public class ConcurrentHashMap<K,V> exte
4710              throw new UnsupportedOperationException();
4711          }
4712  
4713 +        @Override public boolean removeAll(Collection<?> c) {
4714 +            if (c == null) throw new NullPointerException();
4715 +            boolean modified = false;
4716 +            for (Iterator<V> it = iterator(); it.hasNext();) {
4717 +                if (c.contains(it.next())) {
4718 +                    it.remove();
4719 +                    modified = true;
4720 +                }
4721 +            }
4722 +            return modified;
4723 +        }
4724 +
4725 +        public boolean removeIf(Predicate<? super V> filter) {
4726 +            return map.removeValueIf(filter);
4727 +        }
4728 +
4729          public Spliterator<V> spliterator() {
4730              Node<K,V>[] t;
4731              ConcurrentHashMap<K,V> m = map;
# Line 4613 | Line 4795 | public class ConcurrentHashMap<K,V> exte
4795              return added;
4796          }
4797  
4798 +        public boolean removeIf(Predicate<? super Entry<K,V>> filter) {
4799 +            return map.removeEntryIf(filter);
4800 +        }
4801 +
4802          public final int hashCode() {
4803              int h = 0;
4804              Node<K,V>[] t;
# Line 4658 | Line 4844 | public class ConcurrentHashMap<K,V> exte
4844       * Base class for bulk tasks. Repeats some fields and code from
4845       * class Traverser, because we need to subclass CountedCompleter.
4846       */
4847 +    @SuppressWarnings("serial")
4848      abstract static class BulkTask<K,V,R> extends CountedCompleter<R> {
4849          Node<K,V>[] tab;        // same as Traverser
4850          Node<K,V> next;
4851 +        TableStack<K,V> stack, spare;
4852          int index;
4853          int baseIndex;
4854          int baseLimit;
# Line 4682 | Line 4870 | public class ConcurrentHashMap<K,V> exte
4870          }
4871  
4872          /**
4873 <         * Same as Traverser version
4873 >         * Same as Traverser version.
4874           */
4875          final Node<K,V> advance() {
4876              Node<K,V> e;
4877              if ((e = next) != null)
4878                  e = e.next;
4879              for (;;) {
4880 <                Node<K,V>[] t; int i, n; K ek;  // must use locals in checks
4880 >                Node<K,V>[] t; int i, n;
4881                  if (e != null)
4882                      return next = e;
4883                  if (baseIndex >= baseLimit || (t = tab) == null ||
4884                      (n = t.length) <= (i = index) || i < 0)
4885                      return next = null;
4886 <                if ((e = tabAt(t, index)) != null && e.hash < 0) {
4886 >                if ((e = tabAt(t, i)) != null && e.hash < 0) {
4887                      if (e instanceof ForwardingNode) {
4888                          tab = ((ForwardingNode<K,V>)e).nextTable;
4889                          e = null;
4890 +                        pushState(t, i, n);
4891                          continue;
4892                      }
4893                      else if (e instanceof TreeBin)
# Line 4706 | Line 4895 | public class ConcurrentHashMap<K,V> exte
4895                      else
4896                          e = null;
4897                  }
4898 <                if ((index += baseSize) >= n)
4899 <                    index = ++baseIndex;    // visit upper slots if present
4898 >                if (stack != null)
4899 >                    recoverState(n);
4900 >                else if ((index = i + baseSize) >= n)
4901 >                    index = ++baseIndex;
4902              }
4903          }
4904 +
4905 +        private void pushState(Node<K,V>[] t, int i, int n) {
4906 +            TableStack<K,V> s = spare;
4907 +            if (s != null)
4908 +                spare = s.next;
4909 +            else
4910 +                s = new TableStack<K,V>();
4911 +            s.tab = t;
4912 +            s.length = n;
4913 +            s.index = i;
4914 +            s.next = stack;
4915 +            stack = s;
4916 +        }
4917 +
4918 +        private void recoverState(int n) {
4919 +            TableStack<K,V> s; int len;
4920 +            while ((s = stack) != null && (index += (len = s.length)) >= n) {
4921 +                n = len;
4922 +                index = s.index;
4923 +                tab = s.tab;
4924 +                s.tab = null;
4925 +                TableStack<K,V> next = s.next;
4926 +                s.next = spare; // save for reuse
4927 +                stack = next;
4928 +                spare = s;
4929 +            }
4930 +            if (s == null && (index += baseSize) >= n)
4931 +                index = ++baseIndex;
4932 +        }
4933      }
4934  
4935      /*
# Line 5168 | Line 5388 | public class ConcurrentHashMap<K,V> exte
5388                  result = r;
5389                  CountedCompleter<?> c;
5390                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5391 <                    @SuppressWarnings("unchecked") ReduceKeysTask<K,V>
5391 >                    @SuppressWarnings("unchecked")
5392 >                    ReduceKeysTask<K,V>
5393                          t = (ReduceKeysTask<K,V>)c,
5394                          s = t.rights;
5395                      while (s != null) {
# Line 5215 | Line 5436 | public class ConcurrentHashMap<K,V> exte
5436                  result = r;
5437                  CountedCompleter<?> c;
5438                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5439 <                    @SuppressWarnings("unchecked") ReduceValuesTask<K,V>
5439 >                    @SuppressWarnings("unchecked")
5440 >                    ReduceValuesTask<K,V>
5441                          t = (ReduceValuesTask<K,V>)c,
5442                          s = t.rights;
5443                      while (s != null) {
# Line 5260 | Line 5482 | public class ConcurrentHashMap<K,V> exte
5482                  result = r;
5483                  CountedCompleter<?> c;
5484                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5485 <                    @SuppressWarnings("unchecked") ReduceEntriesTask<K,V>
5485 >                    @SuppressWarnings("unchecked")
5486 >                    ReduceEntriesTask<K,V>
5487                          t = (ReduceEntriesTask<K,V>)c,
5488                          s = t.rights;
5489                      while (s != null) {
# Line 5313 | Line 5536 | public class ConcurrentHashMap<K,V> exte
5536                  result = r;
5537                  CountedCompleter<?> c;
5538                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5539 <                    @SuppressWarnings("unchecked") MapReduceKeysTask<K,V,U>
5539 >                    @SuppressWarnings("unchecked")
5540 >                    MapReduceKeysTask<K,V,U>
5541                          t = (MapReduceKeysTask<K,V,U>)c,
5542                          s = t.rights;
5543                      while (s != null) {
# Line 5366 | Line 5590 | public class ConcurrentHashMap<K,V> exte
5590                  result = r;
5591                  CountedCompleter<?> c;
5592                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5593 <                    @SuppressWarnings("unchecked") MapReduceValuesTask<K,V,U>
5593 >                    @SuppressWarnings("unchecked")
5594 >                    MapReduceValuesTask<K,V,U>
5595                          t = (MapReduceValuesTask<K,V,U>)c,
5596                          s = t.rights;
5597                      while (s != null) {
# Line 5419 | Line 5644 | public class ConcurrentHashMap<K,V> exte
5644                  result = r;
5645                  CountedCompleter<?> c;
5646                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5647 <                    @SuppressWarnings("unchecked") MapReduceEntriesTask<K,V,U>
5647 >                    @SuppressWarnings("unchecked")
5648 >                    MapReduceEntriesTask<K,V,U>
5649                          t = (MapReduceEntriesTask<K,V,U>)c,
5650                          s = t.rights;
5651                      while (s != null) {
# Line 5472 | Line 5698 | public class ConcurrentHashMap<K,V> exte
5698                  result = r;
5699                  CountedCompleter<?> c;
5700                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5701 <                    @SuppressWarnings("unchecked") MapReduceMappingsTask<K,V,U>
5701 >                    @SuppressWarnings("unchecked")
5702 >                    MapReduceMappingsTask<K,V,U>
5703                          t = (MapReduceMappingsTask<K,V,U>)c,
5704                          s = t.rights;
5705                      while (s != null) {
# Line 5524 | Line 5751 | public class ConcurrentHashMap<K,V> exte
5751                  result = r;
5752                  CountedCompleter<?> c;
5753                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5754 <                    @SuppressWarnings("unchecked") MapReduceKeysToDoubleTask<K,V>
5754 >                    @SuppressWarnings("unchecked")
5755 >                    MapReduceKeysToDoubleTask<K,V>
5756                          t = (MapReduceKeysToDoubleTask<K,V>)c,
5757                          s = t.rights;
5758                      while (s != null) {
# Line 5573 | Line 5801 | public class ConcurrentHashMap<K,V> exte
5801                  result = r;
5802                  CountedCompleter<?> c;
5803                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5804 <                    @SuppressWarnings("unchecked") MapReduceValuesToDoubleTask<K,V>
5804 >                    @SuppressWarnings("unchecked")
5805 >                    MapReduceValuesToDoubleTask<K,V>
5806                          t = (MapReduceValuesToDoubleTask<K,V>)c,
5807                          s = t.rights;
5808                      while (s != null) {
# Line 5622 | Line 5851 | public class ConcurrentHashMap<K,V> exte
5851                  result = r;
5852                  CountedCompleter<?> c;
5853                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5854 <                    @SuppressWarnings("unchecked") MapReduceEntriesToDoubleTask<K,V>
5854 >                    @SuppressWarnings("unchecked")
5855 >                    MapReduceEntriesToDoubleTask<K,V>
5856                          t = (MapReduceEntriesToDoubleTask<K,V>)c,
5857                          s = t.rights;
5858                      while (s != null) {
# Line 5671 | Line 5901 | public class ConcurrentHashMap<K,V> exte
5901                  result = r;
5902                  CountedCompleter<?> c;
5903                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5904 <                    @SuppressWarnings("unchecked") MapReduceMappingsToDoubleTask<K,V>
5904 >                    @SuppressWarnings("unchecked")
5905 >                    MapReduceMappingsToDoubleTask<K,V>
5906                          t = (MapReduceMappingsToDoubleTask<K,V>)c,
5907                          s = t.rights;
5908                      while (s != null) {
# Line 5720 | Line 5951 | public class ConcurrentHashMap<K,V> exte
5951                  result = r;
5952                  CountedCompleter<?> c;
5953                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
5954 <                    @SuppressWarnings("unchecked") MapReduceKeysToLongTask<K,V>
5954 >                    @SuppressWarnings("unchecked")
5955 >                    MapReduceKeysToLongTask<K,V>
5956                          t = (MapReduceKeysToLongTask<K,V>)c,
5957                          s = t.rights;
5958                      while (s != null) {
# Line 5769 | Line 6001 | public class ConcurrentHashMap<K,V> exte
6001                  result = r;
6002                  CountedCompleter<?> c;
6003                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6004 <                    @SuppressWarnings("unchecked") MapReduceValuesToLongTask<K,V>
6004 >                    @SuppressWarnings("unchecked")
6005 >                    MapReduceValuesToLongTask<K,V>
6006                          t = (MapReduceValuesToLongTask<K,V>)c,
6007                          s = t.rights;
6008                      while (s != null) {
# Line 5818 | Line 6051 | public class ConcurrentHashMap<K,V> exte
6051                  result = r;
6052                  CountedCompleter<?> c;
6053                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6054 <                    @SuppressWarnings("unchecked") MapReduceEntriesToLongTask<K,V>
6054 >                    @SuppressWarnings("unchecked")
6055 >                    MapReduceEntriesToLongTask<K,V>
6056                          t = (MapReduceEntriesToLongTask<K,V>)c,
6057                          s = t.rights;
6058                      while (s != null) {
# Line 5867 | Line 6101 | public class ConcurrentHashMap<K,V> exte
6101                  result = r;
6102                  CountedCompleter<?> c;
6103                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6104 <                    @SuppressWarnings("unchecked") MapReduceMappingsToLongTask<K,V>
6104 >                    @SuppressWarnings("unchecked")
6105 >                    MapReduceMappingsToLongTask<K,V>
6106                          t = (MapReduceMappingsToLongTask<K,V>)c,
6107                          s = t.rights;
6108                      while (s != null) {
# Line 5916 | Line 6151 | public class ConcurrentHashMap<K,V> exte
6151                  result = r;
6152                  CountedCompleter<?> c;
6153                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6154 <                    @SuppressWarnings("unchecked") MapReduceKeysToIntTask<K,V>
6154 >                    @SuppressWarnings("unchecked")
6155 >                    MapReduceKeysToIntTask<K,V>
6156                          t = (MapReduceKeysToIntTask<K,V>)c,
6157                          s = t.rights;
6158                      while (s != null) {
# Line 5965 | Line 6201 | public class ConcurrentHashMap<K,V> exte
6201                  result = r;
6202                  CountedCompleter<?> c;
6203                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6204 <                    @SuppressWarnings("unchecked") MapReduceValuesToIntTask<K,V>
6204 >                    @SuppressWarnings("unchecked")
6205 >                    MapReduceValuesToIntTask<K,V>
6206                          t = (MapReduceValuesToIntTask<K,V>)c,
6207                          s = t.rights;
6208                      while (s != null) {
# Line 6014 | Line 6251 | public class ConcurrentHashMap<K,V> exte
6251                  result = r;
6252                  CountedCompleter<?> c;
6253                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6254 <                    @SuppressWarnings("unchecked") MapReduceEntriesToIntTask<K,V>
6254 >                    @SuppressWarnings("unchecked")
6255 >                    MapReduceEntriesToIntTask<K,V>
6256                          t = (MapReduceEntriesToIntTask<K,V>)c,
6257                          s = t.rights;
6258                      while (s != null) {
# Line 6063 | Line 6301 | public class ConcurrentHashMap<K,V> exte
6301                  result = r;
6302                  CountedCompleter<?> c;
6303                  for (c = firstComplete(); c != null; c = c.nextComplete()) {
6304 <                    @SuppressWarnings("unchecked") MapReduceMappingsToIntTask<K,V>
6304 >                    @SuppressWarnings("unchecked")
6305 >                    MapReduceMappingsToIntTask<K,V>
6306                          t = (MapReduceMappingsToIntTask<K,V>)c,
6307                          s = t.rights;
6308                      while (s != null) {
# Line 6076 | Line 6315 | public class ConcurrentHashMap<K,V> exte
6315      }
6316  
6317      // Unsafe mechanics
6318 <    private static final sun.misc.Unsafe U;
6318 >    private static final Unsafe U = Unsafe.getUnsafe();
6319      private static final long SIZECTL;
6320      private static final long TRANSFERINDEX;
6082    private static final long TRANSFERORIGIN;
6321      private static final long BASECOUNT;
6322      private static final long CELLSBUSY;
6323      private static final long CELLVALUE;
6324 <    private static final long ABASE;
6324 >    private static final int ABASE;
6325      private static final int ASHIFT;
6326  
6327      static {
6328 <        try {
6329 <            U = sun.misc.Unsafe.getUnsafe();
6330 <            Class<?> k = ConcurrentHashMap.class;
6331 <            SIZECTL = U.objectFieldOffset
6332 <                (k.getDeclaredField("sizeCtl"));
6333 <            TRANSFERINDEX = U.objectFieldOffset
6334 <                (k.getDeclaredField("transferIndex"));
6335 <            TRANSFERORIGIN = U.objectFieldOffset
6336 <                (k.getDeclaredField("transferOrigin"));
6337 <            BASECOUNT = U.objectFieldOffset
6338 <                (k.getDeclaredField("baseCount"));
6339 <            CELLSBUSY = U.objectFieldOffset
6340 <                (k.getDeclaredField("cellsBusy"));
6341 <            Class<?> ck = CounterCell.class;
6342 <            CELLVALUE = U.objectFieldOffset
6343 <                (ck.getDeclaredField("value"));
6344 <            Class<?> ak = Node[].class;
6345 <            ABASE = U.arrayBaseOffset(ak);
6346 <            int scale = U.arrayIndexScale(ak);
6347 <            if ((scale & (scale - 1)) != 0)
6348 <                throw new Error("data type scale not a power of two");
6349 <            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6350 <        } catch (Exception e) {
6351 <            throw new Error(e);
6114 <        }
6328 >        SIZECTL = U.objectFieldOffset
6329 >            (ConcurrentHashMap.class, "sizeCtl");
6330 >        TRANSFERINDEX = U.objectFieldOffset
6331 >            (ConcurrentHashMap.class, "transferIndex");
6332 >        BASECOUNT = U.objectFieldOffset
6333 >            (ConcurrentHashMap.class, "baseCount");
6334 >        CELLSBUSY = U.objectFieldOffset
6335 >            (ConcurrentHashMap.class, "cellsBusy");
6336 >
6337 >        CELLVALUE = U.objectFieldOffset
6338 >            (CounterCell.class, "value");
6339 >
6340 >        ABASE = U.arrayBaseOffset(Node[].class);
6341 >        int scale = U.arrayIndexScale(Node[].class);
6342 >        if ((scale & (scale - 1)) != 0)
6343 >            throw new ExceptionInInitializerError("array index scale not a power of two");
6344 >        ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
6345 >
6346 >        // Reduce the risk of rare disastrous classloading in first call to
6347 >        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
6348 >        Class<?> ensureLoaded = LockSupport.class;
6349 >
6350 >        // Eager class load observed to help JIT during startup
6351 >        ensureLoaded = ReservationNode.class;
6352      }
6353   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines