Improve performance of compilation of large code bases

This commit is contained in:
Alexey Andreev 2018-07-31 12:14:53 +03:00
parent 5b5417d46b
commit 67afe6173e
3 changed files with 21 additions and 24 deletions

View File

@ -429,7 +429,7 @@ public class DependencyAnalyzer implements DependencyInfo {
parameterNodes[i + 1] = createNode(arguments[i]); parameterNodes[i + 1] = createNode(arguments[i]);
parameterNodes[i + 1].method = methodRef; parameterNodes[i + 1].method = methodRef;
if (shouldTag) { if (shouldTag) {
parameterNodes[i].setTag(methodRef + ":" + i); parameterNodes[i + 1].setTag(methodRef + ":" + (i + 1));
} }
} }

View File

@ -21,6 +21,7 @@ import org.teavm.model.ValueType;
public class DependencyNode implements ValueDependencyInfo { public class DependencyNode implements ValueDependencyInfo {
private static final int SMALL_TYPES_THRESHOLD = 3; private static final int SMALL_TYPES_THRESHOLD = 3;
private static final int DEGREE_THRESHOLD = 2;
private DependencyAnalyzer dependencyAnalyzer; private DependencyAnalyzer dependencyAnalyzer;
private List<DependencyConsumer> followers; private List<DependencyConsumer> followers;
private int[] smallTypes; private int[] smallTypes;
@ -89,7 +90,7 @@ public class DependencyNode implements ValueDependencyInfo {
} }
public void propagate(DependencyType type) { public void propagate(DependencyType type) {
if (degree > 2) { if (degree > DEGREE_THRESHOLD) {
return; return;
} }
if (addType(type) && filter(type)) { if (addType(type) && filter(type)) {
@ -102,20 +103,20 @@ public class DependencyNode implements ValueDependencyInfo {
private void scheduleSingleType(DependencyType type) { private void scheduleSingleType(DependencyType type) {
if (followers != null) { if (followers != null) {
for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[0])) { for (DependencyConsumer consumer : followers.toArray(new DependencyConsumer[followers.size()])) {
dependencyAnalyzer.schedulePropagation(consumer, type); dependencyAnalyzer.schedulePropagation(consumer, type);
} }
} }
if (transitions != null) { if (transitions != null) {
for (DependencyNodeToNodeTransition consumer : transitions.values().toArray( for (DependencyNodeToNodeTransition consumer : transitions.values().toArray(
new DependencyNodeToNodeTransition[0])) { new DependencyNodeToNodeTransition[transitions.size()])) {
dependencyAnalyzer.schedulePropagation(consumer, type); dependencyAnalyzer.schedulePropagation(consumer, type);
} }
} }
} }
public void propagate(DependencyType[] newTypes) { public void propagate(DependencyType[] newTypes) {
if (degree > 2) { if (degree > DEGREE_THRESHOLD) {
return; return;
} }
@ -213,6 +214,19 @@ public class DependencyNode implements ValueDependencyInfo {
} }
propagateTypes(transition); propagateTypes(transition);
if (degree <= DEGREE_THRESHOLD && node.degree <= DEGREE_THRESHOLD) {
if (arrayItemNode != null && node.arrayItemNode == null) {
node.arrayItemNode = arrayItemNode;
} else if (node.arrayItemNode != null && arrayItemNode == null) {
arrayItemNode = node.arrayItemNode;
} else if (node.arrayItemNode == null && arrayItemNode == null) {
node.arrayItemNode = getArrayItem();
} else {
arrayItemNode.connect(node.arrayItemNode);
node.arrayItemNode.connect(arrayItemNode);
}
}
} }
private void propagateTypes(DependencyConsumer transition) { private void propagateTypes(DependencyConsumer transition) {

View File

@ -34,16 +34,7 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
@Override @Override
public void consume(DependencyType type) { public void consume(DependencyType type) {
if (type.getName().startsWith("[")) { if (type.getName().equals("java.lang.Class")) {
if (!filterType(type)) {
return;
}
source.getArrayItem().connect(destination.getArrayItem());
destination.getArrayItem().connect(source.getArrayItem());
if (!destination.hasType(type)) {
destination.propagate(type);
}
} else if (type.getName().equals("java.lang.Class")) {
if (!filterType(type)) { if (!filterType(type)) {
return; return;
} }
@ -70,10 +61,6 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
added = true; added = true;
} }
if (type.getName().startsWith("[")) {
source.getArrayItem().connect(destination.getArrayItem());
destination.getArrayItem().connect(source.getArrayItem());
}
if (type.getName().equals("java.lang.Class")) { if (type.getName().equals("java.lang.Class")) {
source.getClassValueNode().connect(destination.getClassValueNode()); source.getClassValueNode().connect(destination.getClassValueNode());
} }
@ -91,10 +78,6 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
added = true; added = true;
} }
if (type.getName().startsWith("[")) {
source.getArrayItem().connect(destination.getArrayItem());
destination.getArrayItem().connect(source.getArrayItem());
}
if (type.getName().equals("java.lang.Class")) { if (type.getName().equals("java.lang.Class")) {
source.getClassValueNode().connect(destination.getClassValueNode()); source.getClassValueNode().connect(destination.getClassValueNode());
} }
@ -121,7 +104,7 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
} }
} }
private boolean filterType(DependencyType type) { boolean filterType(DependencyType type) {
if (filter == null) { if (filter == null) {
return true; return true;
} }