531 |
|
/* |
532 |
|
* Encodings for Node hash fields. See above for explanation. |
533 |
|
*/ |
534 |
< |
static final int MOVED = 0x8fffffff; // (-1) hash for forwarding nodes |
535 |
< |
static final int TREEBIN = 0x80000000; // hash for roots of trees |
536 |
< |
static final int RESERVED = 0x80000001; // hash for transient reservations |
534 |
> |
static final int MOVED = -1; // hash for forwarding nodes |
535 |
> |
static final int TREEBIN = -2; // hash for roots of trees |
536 |
> |
static final int RESERVED = -3; // hash for transient reservations |
537 |
|
static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash |
538 |
|
|
539 |
|
/** Number of CPUS, to place bounds on some sizings */ |
560 |
|
final int hash; |
561 |
|
final K key; |
562 |
|
volatile V val; |
563 |
< |
Node<K,V> next; |
563 |
> |
volatile Node<K,V> next; |
564 |
|
|
565 |
|
Node(int hash, K key, V val, Node<K,V> next) { |
566 |
|
this.hash = hash; |
685 |
|
* errors by users, these checks must operate on local variables, |
686 |
|
* which accounts for some odd-looking inline assignments below. |
687 |
|
* Note that calls to setTabAt always occur within locked regions, |
688 |
< |
* and so do not need full volatile semantics, but still require |
689 |
< |
* ordering to maintain concurrent readability. |
688 |
> |
* and so in principle require only release ordering, not need |
689 |
> |
* full volatile semantics, but are currently coded as volatile |
690 |
> |
* writes to be conservative. |
691 |
|
*/ |
692 |
|
|
693 |
|
@SuppressWarnings("unchecked") |
701 |
|
} |
702 |
|
|
703 |
|
static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { |
704 |
< |
U.putOrderedObject(tab, ((long)i << ASHIFT) + ABASE, v); |
704 |
> |
U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); |
705 |
|
} |
706 |
|
|
707 |
|
/* ---------------- Fields -------------- */ |
2358 |
|
else |
2359 |
|
hn = new Node<K,V>(ph, pk, pv, hn); |
2360 |
|
} |
2361 |
+ |
setTabAt(nextTab, i, ln); |
2362 |
+ |
setTabAt(nextTab, i + n, hn); |
2363 |
+ |
setTabAt(tab, i, fwd); |
2364 |
+ |
advance = true; |
2365 |
|
} |
2366 |
|
else if (f instanceof TreeBin) { |
2367 |
|
TreeBin<K,V> t = (TreeBin<K,V>)f; |
2393 |
|
(hc != 0) ? new TreeBin<K,V>(lo) : t; |
2394 |
|
hn = (hc <= UNTREEIFY_THRESHOLD) ? untreeify(hi) : |
2395 |
|
(lc != 0) ? new TreeBin<K,V>(hi) : t; |
2396 |
+ |
setTabAt(nextTab, i, ln); |
2397 |
+ |
setTabAt(nextTab, i + n, hn); |
2398 |
+ |
setTabAt(tab, i, fwd); |
2399 |
+ |
advance = true; |
2400 |
|
} |
2392 |
– |
else |
2393 |
– |
ln = hn = null; |
2394 |
– |
setTabAt(nextTab, i, ln); |
2395 |
– |
setTabAt(nextTab, i + n, hn); |
2396 |
– |
setTabAt(tab, i, fwd); |
2397 |
– |
advance = true; |
2401 |
|
} |
2402 |
|
} |
2403 |
|
} |
2523 |
|
U.compareAndSwapInt(this, SIZECTL, sc, -2)) |
2524 |
|
transfer(tab, null); |
2525 |
|
} |
2526 |
< |
else if ((b = tabAt(tab, index)) != null) { |
2526 |
> |
else if ((b = tabAt(tab, index)) != null && b.hash >= 0) { |
2527 |
|
synchronized (b) { |
2528 |
|
if (tabAt(tab, index) == b) { |
2529 |
|
TreeNode<K,V> hd = null, tl = null; |