Remove performance optimization that causes bug when modifying class hierarchy within class transformers

This commit is contained in:
Alexey Andreev 2019-12-04 12:41:41 +03:00
parent 4b3a8e757b
commit e147a998e5
4 changed files with 13 additions and 43 deletions

View File

@ -81,7 +81,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
|| shouldLog; || shouldLog;
static final boolean dependencyReport = System.getProperty("org.teavm.dependencyReport", "false").equals("true"); static final boolean dependencyReport = System.getProperty("org.teavm.dependencyReport", "false").equals("true");
private int classNameSuffix; private int classNameSuffix;
private ClassReaderSource unprocessedClassSource;
private DependencyClassSource classSource; private DependencyClassSource classSource;
ClassReaderSource agentClassSource; ClassReaderSource agentClassSource;
private ClassLoader classLoader; private ClassLoader classLoader;
@ -118,7 +117,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
Diagnostics diagnostics, ReferenceCache referenceCache) { Diagnostics diagnostics, ReferenceCache referenceCache) {
unprocessedClassSource = classSource;
this.diagnostics = diagnostics; this.diagnostics = diagnostics;
this.referenceCache = referenceCache; this.referenceCache = referenceCache;
this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache); this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache);
@ -170,32 +168,10 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
type = new DependencyType(this, name, types.size()); type = new DependencyType(this, name, types.size());
types.add(type); types.add(type);
typeMap.put(name, type); typeMap.put(name, type);
if (!name.startsWith("[") && !name.startsWith("~")) {
markSupertypesAsHavingSubtypes(name);
}
} }
return type; return type;
} }
private void markSupertypesAsHavingSubtypes(String name) {
ClassReader cls = unprocessedClassSource.get(name);
if (cls == null) {
cls = classSource.get(name);
if (cls == null) {
return;
}
}
if (cls.getParent() != null) {
getType(cls.getParent()).subtypeExists = true;
}
for (String itf : cls.getInterfaces()) {
getType(itf).subtypeExists = true;
}
}
public DependencyNode createNode() { public DependencyNode createNode() {
return createNode(null); return createNode(null);
} }
@ -773,7 +749,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
classSource.cleanup(); classSource.cleanup();
agent.cleanup(); agent.cleanup();
listeners.clear(); listeners.clear();
unprocessedClassSource = null;
classSource.innerHierarchy = null; classSource.innerHierarchy = null;
agentClassSource = classSourcePacker.pack(classSource, agentClassSource = classSourcePacker.pack(classSource,
@ -869,7 +844,7 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
ValueType.Object itemType = (ValueType.Object) ValueType.parse(superClass.substring(1)); ValueType.Object itemType = (ValueType.Object) ValueType.parse(superClass.substring(1));
result = new SuperArrayFilter(this, getSuperClassFilter(itemType.getClassName())); result = new SuperArrayFilter(this, getSuperClassFilter(itemType.getClassName()));
} else { } else {
result = new ExactTypeFilter(superClass); result = new ExactTypeFilter(getType(superClass));
} }
} else { } else {
if (superClass.equals("java.lang.Object")) { if (superClass.equals("java.lang.Object")) {

View File

@ -19,7 +19,6 @@ public class DependencyType {
private DependencyAnalyzer dependencyAnalyzer; private DependencyAnalyzer dependencyAnalyzer;
private String name; private String name;
int index; int index;
boolean subtypeExists;
DependencyType(DependencyAnalyzer dependencyAnalyzer, String name, int index) { DependencyType(DependencyAnalyzer dependencyAnalyzer, String name, int index) {
this.dependencyAnalyzer = dependencyAnalyzer; this.dependencyAnalyzer = dependencyAnalyzer;

View File

@ -15,12 +15,17 @@
*/ */
package org.teavm.dependency; package org.teavm.dependency;
import java.util.BitSet;
class ExactTypeFilter implements DependencyTypeFilter { class ExactTypeFilter implements DependencyTypeFilter {
private static final int[] EMPTY = new int[0];
String typeName; String typeName;
int cache = -1; int cache = -1;
int index;
ExactTypeFilter(String typeName) { ExactTypeFilter(DependencyType dependencyType) {
this.typeName = typeName; this.typeName = dependencyType.getName();
index = dependencyType.index;
} }
@Override @Override
@ -34,4 +39,9 @@ class ExactTypeFilter implements DependencyTypeFilter {
} }
return result; return result;
} }
@Override
public int[] tryExtract(BitSet types) {
return types.get(index) ? new int[] { index } : EMPTY;
}
} }

View File

@ -19,22 +19,16 @@ import java.util.BitSet;
import org.teavm.common.OptionalPredicate; import org.teavm.common.OptionalPredicate;
class SuperClassFilter implements DependencyTypeFilter { class SuperClassFilter implements DependencyTypeFilter {
private static final int[] EMPTY_ARRAY = new int[0];
private DependencyType superType;
private OptionalPredicate<String> predicate; private OptionalPredicate<String> predicate;
private BitSet knownTypes = new BitSet(); private BitSet knownTypes = new BitSet();
private BitSet cache = new BitSet(); private BitSet cache = new BitSet();
SuperClassFilter(DependencyAnalyzer dependencyAnalyzer, DependencyType superType) { SuperClassFilter(DependencyAnalyzer dependencyAnalyzer, DependencyType superType) {
this.superType = superType;
predicate = dependencyAnalyzer.getClassHierarchy().getSuperclassPredicate(superType.getName()); predicate = dependencyAnalyzer.getClassHierarchy().getSuperclassPredicate(superType.getName());
} }
@Override @Override
public boolean match(DependencyType type) { public boolean match(DependencyType type) {
if (!superType.subtypeExists) {
return superType.index == type.index;
}
if (knownTypes.get(type.index)) { if (knownTypes.get(type.index)) {
return cache.get(type.index); return cache.get(type.index);
} }
@ -43,12 +37,4 @@ class SuperClassFilter implements DependencyTypeFilter {
cache.set(type.index, result); cache.set(type.index, result);
return result; return result;
} }
@Override
public int[] tryExtract(BitSet types) {
if (superType.subtypeExists) {
return null;
}
return types.get(superType.index) ? new int[] { superType.index } : EMPTY_ARRAY;
}
} }