mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix NPE in dependency analyzer. Fix excessive types propagating in dependency analyzer
This commit is contained in:
parent
558c3f2f1e
commit
d6363c5fbf
|
@ -460,7 +460,9 @@ class DependencyGraphBuilder {
|
|||
return;
|
||||
}
|
||||
}
|
||||
valueNode.connect(receiverNode, dependencyAnalyzer.getSuperClassFilter(targetType.toString()));
|
||||
if (valueNode != null && receiverNode != null) {
|
||||
valueNode.connect(receiverNode, dependencyAnalyzer.getSuperClassFilter(targetType.toString()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (valueNode != null && receiverNode != null) {
|
||||
|
|
|
@ -33,7 +33,7 @@ import org.teavm.model.ValueType;
|
|||
public class DependencyNode implements ValueDependencyInfo {
|
||||
private static final int SMALL_TYPES_THRESHOLD = 3;
|
||||
private static final int DEGREE_THRESHOLD = 2;
|
||||
private DependencyAnalyzer dependencyAnalyzer;
|
||||
DependencyAnalyzer dependencyAnalyzer;
|
||||
List<DependencyConsumer> followers;
|
||||
TypeSet typeSet;
|
||||
ObjectObjectHashMap<DependencyNode, DependencyNodeToNodeTransition> transitions;
|
||||
|
@ -46,11 +46,10 @@ public class DependencyNode implements ValueDependencyInfo {
|
|||
private int degree;
|
||||
boolean locked;
|
||||
MethodReference method;
|
||||
private ValueType typeFilter;
|
||||
ValueType typeFilter;
|
||||
private DependencyTypeFilter cachedTypeFilter;
|
||||
|
||||
boolean visitedFlag;
|
||||
int splitCount;
|
||||
|
||||
DependencyNode(DependencyAnalyzer dependencyAnalyzer, ValueType typeFilter) {
|
||||
this(dependencyAnalyzer, typeFilter, 0);
|
||||
|
@ -287,7 +286,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
|||
typeSet.transitions.add(transition);
|
||||
}
|
||||
|
||||
node.propagate(getTypesInternal());
|
||||
node.propagate(filter != null ? getTypesInternal(filter) : getTypesInternal());
|
||||
}
|
||||
|
||||
connectArrayItemNodes(node);
|
||||
|
@ -446,6 +445,21 @@ public class DependencyNode implements ValueDependencyInfo {
|
|||
return i == result.length ? result : Arrays.copyOf(result, i);
|
||||
}
|
||||
|
||||
DependencyType[] getTypesInternal(DependencyTypeFilter filter) {
|
||||
if (typeSet == null) {
|
||||
return new DependencyType[0];
|
||||
}
|
||||
DependencyType[] types = typeSet.getTypes();
|
||||
DependencyType[] result = new DependencyType[types.length];
|
||||
int i = 0;
|
||||
for (DependencyType type : types) {
|
||||
if (filter(type) && filter.match(type)) {
|
||||
result[i++] = type;
|
||||
}
|
||||
}
|
||||
return i == result.length ? result : Arrays.copyOf(result, i);
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
@ -483,7 +497,6 @@ public class DependencyNode implements ValueDependencyInfo {
|
|||
|
||||
for (DependencyNode node : domain) {
|
||||
node.typeSet = typeSet;
|
||||
node.splitCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,7 +515,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
|||
for (ObjectCursor<DependencyNodeToNodeTransition> cursor : node.transitionList) {
|
||||
DependencyNodeToNodeTransition transition = cursor.value;
|
||||
if (transition.filter == null && transition.destination.typeSet == typeSet
|
||||
&& !visited.contains(transition.destination)) {
|
||||
&& !visited.contains(transition.destination) && transition.isDestSubsetOfSrc()) {
|
||||
stack.push(transition.destination);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import com.carrotsearch.hppc.IntSet;
|
|||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collection;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
class DependencyNodeToNodeTransition {
|
||||
DependencyNode source;
|
||||
|
@ -26,6 +28,7 @@ class DependencyNodeToNodeTransition {
|
|||
DependencyTypeFilter filter;
|
||||
private BitSet knownFilteredOffTypes;
|
||||
IntSet pendingTypes;
|
||||
byte destSubsetOfSrc;
|
||||
|
||||
DependencyNodeToNodeTransition(DependencyNode source, DependencyNode destination, DependencyTypeFilter filter) {
|
||||
this.source = source;
|
||||
|
@ -69,7 +72,6 @@ class DependencyNodeToNodeTransition {
|
|||
Collection<DependencyNode> domainToMerge = destination.typeSet.domain;
|
||||
for (DependencyNode node : domainToMerge) {
|
||||
node.typeSet = source.typeSet;
|
||||
node.splitCount++;
|
||||
source.typeSet.domain.add(node);
|
||||
}
|
||||
source.typeSet.invalidate();
|
||||
|
@ -77,7 +79,7 @@ class DependencyNodeToNodeTransition {
|
|||
}
|
||||
|
||||
boolean shouldMergeDomains() {
|
||||
if (filter != null || destination.splitCount > 2) {
|
||||
if (filter != null) {
|
||||
return false;
|
||||
}
|
||||
if (destination.typeSet == null) {
|
||||
|
@ -171,4 +173,25 @@ class DependencyNodeToNodeTransition {
|
|||
boolean pointsToDomainOrigin() {
|
||||
return destination.typeSet == null || destination.typeSet.origin == destination;
|
||||
}
|
||||
|
||||
boolean isDestSubsetOfSrc() {
|
||||
if (destSubsetOfSrc == 0) {
|
||||
destSubsetOfSrc = calculateDestSubsetOfSrc() ? (byte) 2 : 1;
|
||||
}
|
||||
return destSubsetOfSrc == 2;
|
||||
}
|
||||
|
||||
private boolean calculateDestSubsetOfSrc() {
|
||||
if (source.typeFilter == null) {
|
||||
return true;
|
||||
}
|
||||
if (destination.typeFilter == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueType sourceType = source.typeFilter;
|
||||
ValueType destType = destination.typeFilter;
|
||||
ClassReaderSource classSource = source.dependencyAnalyzer.getClassSource();
|
||||
return classSource.isSuperType(sourceType, destType).orElse(false);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user