diff --git a/core/src/main/java/org/teavm/dependency/DependencyChecker.java b/core/src/main/java/org/teavm/dependency/DependencyChecker.java index 5b5e00a54..9d743e888 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -75,7 +75,6 @@ public class DependencyChecker implements DependencyInfo { private Diagnostics diagnostics; DefaultCallGraph callGraph = new DefaultCallGraph(); private DependencyAgent agent; - List nodes = new ArrayList<>(); Map bootstrapMethodSubstitutors = new HashMap<>(); private boolean completing; @@ -134,9 +133,7 @@ public class DependencyChecker implements DependencyInfo { } public DependencyNode createNode() { - DependencyNode node = new DependencyNode(this); - nodes.add(node); - return node; + return new DependencyNode(this); } @Override @@ -235,16 +232,32 @@ public class DependencyChecker implements DependencyInfo { } } + private int propagationDepth; + void schedulePropagation(DependencyConsumer consumer, DependencyType type) { - tasks.add(() -> consumer.consume(type)); + if (propagationDepth < 50) { + ++propagationDepth; + consumer.consume(type); + --propagationDepth; + } else { + tasks.add(() -> consumer.consume(type)); + } } void schedulePropagation(DependencyConsumer consumer, DependencyType[] types) { - tasks.add(() -> { + if (propagationDepth < 50) { + ++propagationDepth; for (DependencyType type : types) { consumer.consume(type); } - }); + --propagationDepth; + } else { + tasks.add(() -> { + for (DependencyType type : types) { + consumer.consume(type); + } + }); + } } private Set classesAddedByRoot = new HashSet<>(); @@ -318,7 +331,7 @@ public class DependencyChecker implements DependencyInfo { throw new IllegalStateException("Can't submit class during completion phase"); } callGraph.getNode(methodRef); - boolean added = true; + boolean added; if (callLocation != null && callLocation.getMethod() != null) { added = callGraph.getNode(callLocation.getMethod()).addCallSite(methodRef, callLocation.getSourceLocation()); @@ -408,7 +421,7 @@ public class DependencyChecker implements DependencyInfo { if (completing) { throw new IllegalStateException("Can't submit class during completion phase"); } - boolean added = true; + boolean added; if (location != null) { added = callGraph.getNode(location.getMethod()).addFieldAccess(fieldRef, location.getSourceLocation()); } else { diff --git a/core/src/main/java/org/teavm/dependency/DependencyNode.java b/core/src/main/java/org/teavm/dependency/DependencyNode.java index 995df8137..48c7e074a 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyNode.java +++ b/core/src/main/java/org/teavm/dependency/DependencyNode.java @@ -99,6 +99,11 @@ public class DependencyNode implements ValueDependencyInfo { dependencyChecker.schedulePropagation(consumer, type); } } + if (transitions != null) { + for (DependencyConsumer consumer : transitions.toArray(new DependencyConsumer[transitions.size()])) { + dependencyChecker.schedulePropagation(consumer, type); + } + } } } @@ -122,22 +127,32 @@ public class DependencyNode implements ValueDependencyInfo { System.out.println(tag + " -> " + types[i].getName()); } } - if (followers != null) { + + if (j < types.length && (followers != null || transitions != null)) { types = Arrays.copyOf(types, j); + } + if (followers != null) { for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) { dependencyChecker.schedulePropagation(consumer, types); } } + if (transitions != null) { + for (DependencyNodeToNodeTransition consumer : transitions.toArray( + new DependencyNodeToNodeTransition[transitions.size()])) { + dependencyChecker.schedulePropagation(consumer, types); + } + } } public void addConsumer(DependencyConsumer consumer) { if (followers == null) { - followers = new ArrayList<>(); + followers = new ArrayList<>(1); } if (followers.contains(consumer)) { return; } followers.add(consumer); + if (this.types != null) { List types = new ArrayList<>(); for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) { @@ -169,14 +184,27 @@ public class DependencyNode implements ValueDependencyInfo { } DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter); if (transitions == null) { - transitions = new ArrayList<>(); + transitions = new ArrayList<>(1); } transitions.add(transition); if (DependencyChecker.shouldLog) { System.out.println("Connecting " + tag + " to " + node.tag); } - addConsumer(transition); + + if (this.types != null) { + List types = new ArrayList<>(); + for (int index = this.types.nextSetBit(0); index >= 0; index = this.types.nextSetBit(index + 1)) { + types.add(dependencyChecker.types.get(index)); + } + dependencyChecker.schedulePropagation(transition, types.toArray(new DependencyType[types.size()])); + } else if (this.smallTypes != null) { + DependencyType[] types = new DependencyType[smallTypes.length]; + for (int i = 0; i < types.length; ++i) { + types[i] = dependencyChecker.types.get(smallTypes[i]); + } + dependencyChecker.schedulePropagation(transition, types); + } } public void connect(DependencyNode node) { @@ -187,7 +215,6 @@ public class DependencyNode implements ValueDependencyInfo { public DependencyNode getArrayItem() { if (arrayItemNode == null) { arrayItemNode = new DependencyNode(dependencyChecker, degree + 1); - dependencyChecker.nodes.add(arrayItemNode); if (DependencyChecker.shouldLog) { arrayItemNode.tag = tag + "["; } @@ -199,7 +226,7 @@ public class DependencyNode implements ValueDependencyInfo { public DependencyNode getClassValueNode() { if (classValueNode == null) { classValueNode = new DependencyNode(dependencyChecker, degree); - dependencyChecker.nodes.add(classValueNode); + classValueNode.classValueNode = classValueNode; if (DependencyChecker.shouldLog) { classValueNode.tag = tag + "@"; }