Skip to content

Commit 90cf54a

Browse files
committed
add cache to avoid synchronization
1 parent 02c88ee commit 90cf54a

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeClass.java

+34
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.util.concurrent.atomic.AtomicInteger;
4545
import java.util.stream.Stream;
4646

47+
import jdk.graal.compiler.nodes.NodeClassMap;
4748
import org.graalvm.collections.EconomicMap;
4849
import org.graalvm.collections.Equivalence;
4950

@@ -1487,4 +1488,37 @@ private static void unregisterAtInputsAsUsageHelperMany(Node node, NodeList<Node
14871488
}
14881489
list.clearWithoutUpdate();
14891490
}
1491+
1492+
/**
1493+
* The cached id for a {@link NodeClass} object in a specific {@link NodeClassMap}.
1494+
*
1495+
* @param map an object whose identity uniquely identifies a {@link NodeClassMap}
1496+
*/
1497+
record CachedId(Object map, Integer id) {
1498+
}
1499+
1500+
private CachedId cachedId;
1501+
1502+
/**
1503+
* Sets the cache for this object's {@code id} in {@code map}.
1504+
*
1505+
* @param map an object whose identity uniquely identifies a {@link NodeClassMap}
1506+
*/
1507+
public void setCachedId(Object map, Integer id) {
1508+
cachedId = new CachedId(map, id);
1509+
}
1510+
1511+
/**
1512+
* Gets the cache for this object's id in {@code map}.
1513+
*
1514+
* @param map an object whose identity uniquely identifies a {@link NodeClassMap}
1515+
* @return null if no cached id for this object in {@code map} is available
1516+
*/
1517+
public Integer getCachedId(Object map) {
1518+
var c = cachedId;
1519+
if (c != null && c.map == map) {
1520+
return c.id;
1521+
}
1522+
return null;
1523+
}
14901524
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/NodeClassMap.java

+24-8
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,35 @@ public NodeClassMap() {
5757
this.values = new NodeClass<?>[INITIAL_CONCRETE_CAPACITY];
5858
}
5959

60+
/**
61+
* An object that is a proxy for this {@link NodeClassMap} in a cache. Using a proxy prevents a
62+
* reference from a {@link NodeClass} to all other entries in a {@link NodeClassMap}. This is
63+
* important in the context of Native Image as some {@link NodeClassMap}s can contain
64+
* hosted-only node classes.
65+
*/
66+
private final Object cacheToken = new Object();
67+
6068
/**
6169
* Gets an id for {@code nc}, creating it first if necessary.
6270
*/
63-
public synchronized int getId(NodeClass<?> nc) {
64-
Integer id = valueToId.get(nc);
71+
public int getId(NodeClass<?> nc) {
72+
// Using a cache entry in `nc` mostly avoids going
73+
// into the synchronized block below.
74+
Integer id = nc.getCachedId(cacheToken);
6575
if (id == null) {
66-
if (size == values.length) {
67-
int growth = (size + 1) >> 1;
68-
values = Arrays.copyOf(values, size + growth);
76+
synchronized (this) {
77+
id = valueToId.get(nc);
78+
if (id == null) {
79+
if (size == values.length) {
80+
int growth = (size + 1) >> 1;
81+
values = Arrays.copyOf(values, size + growth);
82+
}
83+
id = size++;
84+
valueToId.put(nc, id);
85+
values[id] = nc;
86+
}
6987
}
70-
id = size++;
71-
valueToId.put(nc, id);
72-
values[id] = nc;
88+
nc.setCachedId(cacheToken, id);
7389
}
7490
return id;
7591
}

0 commit comments

Comments
 (0)