719 |
|
/* ---------------- Table element access -------------- */ |
720 |
|
|
721 |
|
/* |
722 |
< |
* Volatile access methods are used for table elements as well as |
722 |
> |
* Atomic access methods are used for table elements as well as |
723 |
|
* elements of in-progress next table while resizing. All uses of |
724 |
|
* the tab arguments must be null checked by callers. All callers |
725 |
|
* also paranoically precheck that tab's length is not zero (or an |
729 |
|
* errors by users, these checks must operate on local variables, |
730 |
|
* which accounts for some odd-looking inline assignments below. |
731 |
|
* Note that calls to setTabAt always occur within locked regions, |
732 |
< |
* and so in principle require only release ordering, not |
733 |
< |
* full volatile semantics, but are currently coded as volatile |
734 |
< |
* writes to be conservative. |
732 |
> |
* and so require only release ordering. |
733 |
|
*/ |
734 |
|
|
735 |
|
@SuppressWarnings("unchecked") |
736 |
|
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) { |
737 |
< |
return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); |
737 |
> |
return (Node<K,V>)U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE); |
738 |
|
} |
739 |
|
|
740 |
|
static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i, |
743 |
|
} |
744 |
|
|
745 |
|
static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) { |
746 |
< |
U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); |
746 |
> |
U.putObjectRelease(tab, ((long)i << ASHIFT) + ABASE, v); |
747 |
|
} |
748 |
|
|
749 |
|
/* ---------------- Fields -------------- */ |