Fix bug in dependency analyzer

This commit is contained in:
Alexey Andreev 2018-10-19 14:47:20 +03:00
parent ac2bd7599b
commit 8a55510d4f
4 changed files with 24 additions and 25 deletions

View File

@ -75,7 +75,7 @@ public class DependencyAnalyzer implements DependencyInfo {
private CachedMapper<String, ClassDependency> classCache; private CachedMapper<String, ClassDependency> classCache;
private List<DependencyListener> listeners = new ArrayList<>(); private List<DependencyListener> listeners = new ArrayList<>();
private ServiceRepository services; private ServiceRepository services;
private Deque<DependencyNodeToNodeTransition> pendingTransitions = new ArrayDeque<>(); private Deque<Transition> pendingTransitions = new ArrayDeque<>();
private Deque<Runnable> tasks = new ArrayDeque<>(); private Deque<Runnable> tasks = new ArrayDeque<>();
private Queue<Runnable> deferredTasks = new ArrayDeque<>(); private Queue<Runnable> deferredTasks = new ArrayDeque<>();
List<DependencyType> types = new ArrayList<>(); List<DependencyType> types = new ArrayList<>();
@ -275,7 +275,7 @@ public class DependencyAnalyzer implements DependencyInfo {
} }
} }
void schedulePropagation(DependencyNodeToNodeTransition consumer, DependencyType type) { void schedulePropagation(Transition consumer, DependencyType type) {
if (!consumer.destination.filter(type)) { if (!consumer.destination.filter(type)) {
return; return;
} }
@ -294,7 +294,7 @@ public class DependencyAnalyzer implements DependencyInfo {
} }
} }
void schedulePropagation(DependencyNodeToNodeTransition consumer, DependencyType[] types) { void schedulePropagation(Transition consumer, DependencyType[] types) {
if (types.length == 0) { if (types.length == 0) {
return; return;
} }
@ -630,7 +630,7 @@ public class DependencyAnalyzer implements DependencyInfo {
private void processNodeToNodeTransitionQueue() { private void processNodeToNodeTransitionQueue() {
while (!pendingTransitions.isEmpty()) { while (!pendingTransitions.isEmpty()) {
DependencyNodeToNodeTransition transition = pendingTransitions.remove(); Transition transition = pendingTransitions.remove();
IntSet pendingTypes = transition.pendingTypes; IntSet pendingTypes = transition.pendingTypes;
transition.pendingTypes = null; transition.pendingTypes = null;
if (pendingTypes.size() == 1) { if (pendingTypes.size() == 1) {

View File

@ -36,8 +36,8 @@ public class DependencyNode implements ValueDependencyInfo {
DependencyAnalyzer dependencyAnalyzer; DependencyAnalyzer dependencyAnalyzer;
List<DependencyConsumer> followers; List<DependencyConsumer> followers;
TypeSet typeSet; TypeSet typeSet;
ObjectObjectHashMap<DependencyNode, DependencyNodeToNodeTransition> transitions; ObjectObjectHashMap<DependencyNode, Transition> transitions;
ObjectArrayList<DependencyNodeToNodeTransition> transitionList; ObjectArrayList<Transition> transitionList;
String tag; String tag;
private DependencyNode arrayItemNode; private DependencyNode arrayItemNode;
private DependencyNode classValueNode; private DependencyNode classValueNode;
@ -78,15 +78,15 @@ public class DependencyNode implements ValueDependencyInfo {
} }
} }
ObjectArrayList<DependencyNodeToNodeTransition> transitions = new ObjectArrayList<>(typeSet.getTransitions()); ObjectArrayList<Transition> transitions = new ObjectArrayList<>(typeSet.getTransitions());
List<ConsumerWithNode> consumerEntries = typeSet.getConsumers(); List<ConsumerWithNode> consumerEntries = typeSet.getConsumers();
if (action != null) { if (action != null) {
action.run(); action.run();
} }
for (ObjectCursor<DependencyNodeToNodeTransition> cursor : transitions) { for (ObjectCursor<Transition> cursor : transitions) {
DependencyNodeToNodeTransition transition = cursor.value; Transition transition = cursor.value;
if (transition.source.filter(type) && transition.filterType(type)) { if (transition.source.filter(type) && transition.filterType(type)) {
dependencyAnalyzer.schedulePropagation(transition, type); dependencyAnalyzer.schedulePropagation(transition, type);
} }
@ -156,15 +156,15 @@ public class DependencyNode implements ValueDependencyInfo {
} }
} }
ObjectArrayList<DependencyNodeToNodeTransition> transitions = new ObjectArrayList<>(typeSet.getTransitions()); ObjectArrayList<Transition> transitions = new ObjectArrayList<>(typeSet.getTransitions());
List<ConsumerWithNode> consumerEntries = typeSet.getConsumers(); List<ConsumerWithNode> consumerEntries = typeSet.getConsumers();
if (action != null) { if (action != null) {
action.run(); action.run();
} }
for (ObjectCursor<DependencyNodeToNodeTransition> cursor : transitions) { for (ObjectCursor<Transition> cursor : transitions) {
DependencyNodeToNodeTransition transition = cursor.value; Transition transition = cursor.value;
DependencyType[] typesToPropagate = newTypes; DependencyType[] typesToPropagate = newTypes;
if (transition.source.typeFilter != null || transition.filter != null) { if (transition.source.typeFilter != null || transition.filter != null) {
int j = 0; int j = 0;
@ -276,7 +276,7 @@ public class DependencyNode implements ValueDependencyInfo {
return; return;
} }
DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter); Transition transition = new Transition(this, node, filter);
transitions.put(node, transition); transitions.put(node, transition);
transitionList.add(transition); transitionList.add(transition);
if (DependencyAnalyzer.shouldLog) { if (DependencyAnalyzer.shouldLog) {
@ -358,8 +358,7 @@ public class DependencyNode implements ValueDependencyInfo {
return; return;
} }
for (DependencyNodeToNodeTransition transition : classNodeParent.transitionList for (Transition transition : classNodeParent.transitionList.toArray(Transition.class)) {
.toArray(DependencyNodeToNodeTransition.class)) {
connect(transition.destination.getClassValueNode()); connect(transition.destination.getClassValueNode());
} }
} }
@ -370,7 +369,7 @@ public class DependencyNode implements ValueDependencyInfo {
} }
} }
private void propagateTypes(DependencyNodeToNodeTransition transition) { private void propagateTypes(Transition transition) {
if (typeSet != null) { if (typeSet != null) {
dependencyAnalyzer.schedulePropagation(transition, getTypesInternal()); dependencyAnalyzer.schedulePropagation(transition, getTypesInternal());
} }
@ -522,8 +521,8 @@ public class DependencyNode implements ValueDependencyInfo {
} }
if (node.transitions != null) { if (node.transitions != null) {
for (ObjectCursor<DependencyNodeToNodeTransition> cursor : node.transitionList) { for (ObjectCursor<Transition> cursor : node.transitionList) {
DependencyNodeToNodeTransition transition = cursor.value; Transition transition = cursor.value;
if (transition.filter == null && transition.destination.typeSet == typeSet if (transition.filter == null && transition.destination.typeSet == typeSet
&& !visited.contains(transition.destination) && transition.isDestSubsetOfSrc()) { && !visited.contains(transition.destination) && transition.isDestSubsetOfSrc()) {
stack.push(transition.destination); stack.push(transition.destination);

View File

@ -22,7 +22,7 @@ import java.util.Collection;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
class DependencyNodeToNodeTransition { class Transition {
DependencyNode source; DependencyNode source;
DependencyNode destination; DependencyNode destination;
DependencyTypeFilter filter; DependencyTypeFilter filter;
@ -30,7 +30,7 @@ class DependencyNodeToNodeTransition {
IntHashSet pendingTypes; IntHashSet pendingTypes;
byte destSubsetOfSrc; byte destSubsetOfSrc;
DependencyNodeToNodeTransition(DependencyNode source, DependencyNode destination, DependencyTypeFilter filter) { Transition(DependencyNode source, DependencyNode destination, DependencyTypeFilter filter) {
this.source = source; this.source = source;
this.destination = destination; this.destination = destination;
this.filter = filter; this.filter = filter;
@ -79,7 +79,7 @@ class DependencyNodeToNodeTransition {
} }
boolean shouldMergeDomains() { boolean shouldMergeDomains() {
if (filter != null) { if (filter != null || !isDestSubsetOfSrc()) {
return false; return false;
} }
if (destination.typeSet == null) { if (destination.typeSet == null) {

View File

@ -34,7 +34,7 @@ class TypeSet {
private int typesCount; private int typesCount;
Set<DependencyNode> domain = new LinkedHashSet<>(); Set<DependencyNode> domain = new LinkedHashSet<>();
ObjectArrayList<DependencyNodeToNodeTransition> transitions; ObjectArrayList<Transition> transitions;
ArrayList<ConsumerWithNode> consumers; ArrayList<ConsumerWithNode> consumers;
TypeSet(DependencyAnalyzer dependencyAnalyzer, DependencyNode origin) { TypeSet(DependencyAnalyzer dependencyAnalyzer, DependencyNode origin) {
@ -154,13 +154,13 @@ class TypeSet {
consumers = null; consumers = null;
} }
ObjectArrayList<DependencyNodeToNodeTransition> getTransitions() { ObjectArrayList<Transition> getTransitions() {
if (transitions == null) { if (transitions == null) {
transitions = new ObjectArrayList<>(domain.size() * 2); transitions = new ObjectArrayList<>(domain.size() * 2);
for (DependencyNode node : domain) { for (DependencyNode node : domain) {
if (node.transitions != null) { if (node.transitions != null) {
for (ObjectCursor<DependencyNodeToNodeTransition> cursor : node.transitionList) { for (ObjectCursor<Transition> cursor : node.transitionList) {
DependencyNodeToNodeTransition transition = cursor.value; Transition transition = cursor.value;
if (transition.filter != null || transition.destination.typeSet != this) { if (transition.filter != null || transition.destination.typeSet != this) {
transitions.add(transition); transitions.add(transition);
} }