java-topology/defects/javac/patch/javac-0002-infer-nodeindex-closure-cache.patch

99 lines
4 KiB
Diff

# UNDF: UNDF-2026-000000118
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
index f5e9bfcd..f4bb9a54 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
@@ -1694,6 +1694,9 @@ class Node extends GraphUtils.TarjanNode<ListBuffer<Type>, Node> implements Dott
/** node dependencies */
Set<Node> deps;
+ /** cached transitive closure — invalidated on any structural change */
+ private Set<Node> cachedClosure = null;
+
Node(Type ivar) {
super(ListBuffer.of(ivar));
this.deps = new LinkedHashSet<>();
@@ -1721,6 +1724,7 @@ public Collection<? extends Node> getDependenciesByKind(GraphUtils.DependencyKin
* Adds dependency with given kind.
*/
protected void addDependency(Node depToAdd) {
+ cachedClosure = null;
deps.add(depToAdd);
}
@@ -1737,17 +1741,20 @@ protected void addDependencies(Set<Node> depsToAdd) {
* Remove a dependency, regardless of its kind.
*/
protected boolean removeDependency(Node n) {
+ cachedClosure = null;
return deps.remove(n);
}
/**
* Compute closure of a give node, by recursively walking
- * through all its dependencies.
+ * through all its dependencies. Result is cached; invalidated
+ * by addDependency/removeDependency on any structural change.
*/
protected Set<Node> closure() {
- Set<Node> closure = new LinkedHashSet<>();
- closureInternal(closure);
- return closure;
+ if (cachedClosure != null) return cachedClosure;
+ cachedClosure = new LinkedHashSet<>();
+ closureInternal(cachedClosure);
+ return cachedClosure;
}
private void closureInternal(Set<Node> closure) {
@@ -1839,21 +1846,19 @@ public Properties dependencyAttributes(Node sink, GraphUtils.DependencyKind dk)
/** the nodes in the inference graph */
ArrayList<Node> nodes;
+ /** O(1) lookup index: maps each inference-variable type to its node */
+ Map<Type, Node> nodeIndex = new LinkedHashMap<>();
+
InferenceGraph() {
initNodes();
}
/**
* Basic lookup helper for retrieving a graph node given an inference
- * variable type.
+ * variable type. O(1) via nodeIndex built in initNodes().
*/
public Node findNode(Type t) {
- for (Node n : nodes) {
- if (n.data.contains(t)) {
- return n;
- }
- }
- return null;
+ return nodeIndex.get(t);
}
/**
@@ -1863,6 +1868,9 @@ public Node findNode(Type t) {
public void deleteNode(Node n) {
Assert.check(nodes.contains(n));
nodes.remove(n);
+ for (Type t : n.data) {
+ nodeIndex.remove(t);
+ }
notifyUpdate(n, null);
}
@@ -1916,6 +1924,13 @@ void initNodes() {
acyclicNodes.add(conSubGraph.head);
}
nodes = acyclicNodes;
+ //build O(1) lookup index after merging
+ nodeIndex = new LinkedHashMap<>();
+ for (Node n : nodes) {
+ for (Type t : n.data) {
+ nodeIndex.put(t, n);
+ }
+ }
}
/**