ObjectIdSubclassMap: Avoid field loads in inner loops

Ensure the JIT knows the table cannot be changed during the critical
inner loop of get() or insert() by loading the field into a final
local variable.  This shouldn't be necessary, but the instance member
is declared non-final (to resizing) and it is not very obvious to the
JIT that the table cannot be modified by AnyObjectId.equals().

Simplify the JIT's decision making by making it obvious, these
values cannot change during the critical inner loop, allowing
for better register allocation.

Change-Id: I0d797533fc5327366f1207b0937c406f02cdaab3
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
Shawn O. Pearce 2011-03-09 14:44:14 -08:00
parent df7b192e26
commit c11756ca4e
1 changed files with 14 additions and 8 deletions

View File

@ -93,12 +93,14 @@ public void clear() {
*/
public V get(final AnyObjectId toFind) {
int i = toFind.w1 & mask;
final V[] tbl = table;
final int end = tbl.length;
V obj;
while ((obj = table[i]) != null) {
while ((obj = tbl[i]) != null) {
if (AnyObjectId.equals(obj, toFind))
return obj;
if (++i == table.length)
if (++i == end)
i = 0;
}
return null;
@ -156,12 +158,14 @@ public <Q extends V> void add(final Q newValue) {
*/
public <Q extends V> V addIfAbsent(final Q newValue) {
int i = newValue.w1 & mask;
final V[] tbl = table;
final int end = tbl.length;
V obj;
while ((obj = table[i]) != null) {
while ((obj = tbl[i]) != null) {
if (AnyObjectId.equals(obj, newValue))
return obj;
if (++i == table.length)
if (++i == end)
i = 0;
}
@ -169,7 +173,7 @@ public <Q extends V> V addIfAbsent(final Q newValue) {
grow();
insert(newValue);
} else {
table[i] = newValue;
tbl[i] = newValue;
}
return newValue;
}
@ -215,11 +219,13 @@ public void remove() {
private void insert(final V newValue) {
int j = newValue.w1 & mask;
while (table[j] != null) {
if (++j >= table.length)
final V[] tbl = table;
final int end = tbl.length;
while (tbl[j] != null) {
if (++j == end)
j = 0;
}
table[j] = newValue;
tbl[j] = newValue;
}
private void grow() {