From e147a998e55c2ca7ed7dd1465855e463094bc443 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 4 Dec 2019 12:41:41 +0300 Subject: [PATCH] Remove performance optimization that causes bug when modifying class hierarchy within class transformers --- .../teavm/dependency/DependencyAnalyzer.java | 27 +------------------ .../org/teavm/dependency/DependencyType.java | 1 - .../org/teavm/dependency/ExactTypeFilter.java | 14 ++++++++-- .../teavm/dependency/SuperClassFilter.java | 14 ---------- 4 files changed, 13 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java b/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java index 4e53d444b..c8ffa5898 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java +++ b/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java @@ -81,7 +81,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo { || shouldLog; static final boolean dependencyReport = System.getProperty("org.teavm.dependencyReport", "false").equals("true"); private int classNameSuffix; - private ClassReaderSource unprocessedClassSource; private DependencyClassSource classSource; ClassReaderSource agentClassSource; private ClassLoader classLoader; @@ -118,7 +117,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo { DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, Diagnostics diagnostics, ReferenceCache referenceCache) { - unprocessedClassSource = classSource; this.diagnostics = diagnostics; this.referenceCache = referenceCache; this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache); @@ -170,32 +168,10 @@ public abstract class DependencyAnalyzer implements DependencyInfo { type = new DependencyType(this, name, types.size()); types.add(type); typeMap.put(name, type); - - if (!name.startsWith("[") && !name.startsWith("~")) { - markSupertypesAsHavingSubtypes(name); - } } 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() { return createNode(null); } @@ -773,7 +749,6 @@ public abstract class DependencyAnalyzer implements DependencyInfo { classSource.cleanup(); agent.cleanup(); listeners.clear(); - unprocessedClassSource = null; classSource.innerHierarchy = null; agentClassSource = classSourcePacker.pack(classSource, @@ -869,7 +844,7 @@ public abstract class DependencyAnalyzer implements DependencyInfo { ValueType.Object itemType = (ValueType.Object) ValueType.parse(superClass.substring(1)); result = new SuperArrayFilter(this, getSuperClassFilter(itemType.getClassName())); } else { - result = new ExactTypeFilter(superClass); + result = new ExactTypeFilter(getType(superClass)); } } else { if (superClass.equals("java.lang.Object")) { diff --git a/core/src/main/java/org/teavm/dependency/DependencyType.java b/core/src/main/java/org/teavm/dependency/DependencyType.java index 9422f2c09..56281283f 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyType.java +++ b/core/src/main/java/org/teavm/dependency/DependencyType.java @@ -19,7 +19,6 @@ public class DependencyType { private DependencyAnalyzer dependencyAnalyzer; private String name; int index; - boolean subtypeExists; DependencyType(DependencyAnalyzer dependencyAnalyzer, String name, int index) { this.dependencyAnalyzer = dependencyAnalyzer; diff --git a/core/src/main/java/org/teavm/dependency/ExactTypeFilter.java b/core/src/main/java/org/teavm/dependency/ExactTypeFilter.java index 33f2d664e..783b4dd10 100644 --- a/core/src/main/java/org/teavm/dependency/ExactTypeFilter.java +++ b/core/src/main/java/org/teavm/dependency/ExactTypeFilter.java @@ -15,12 +15,17 @@ */ package org.teavm.dependency; +import java.util.BitSet; + class ExactTypeFilter implements DependencyTypeFilter { + private static final int[] EMPTY = new int[0]; String typeName; int cache = -1; + int index; - ExactTypeFilter(String typeName) { - this.typeName = typeName; + ExactTypeFilter(DependencyType dependencyType) { + this.typeName = dependencyType.getName(); + index = dependencyType.index; } @Override @@ -34,4 +39,9 @@ class ExactTypeFilter implements DependencyTypeFilter { } return result; } + + @Override + public int[] tryExtract(BitSet types) { + return types.get(index) ? new int[] { index } : EMPTY; + } } diff --git a/core/src/main/java/org/teavm/dependency/SuperClassFilter.java b/core/src/main/java/org/teavm/dependency/SuperClassFilter.java index 0c94af4bf..11917393e 100644 --- a/core/src/main/java/org/teavm/dependency/SuperClassFilter.java +++ b/core/src/main/java/org/teavm/dependency/SuperClassFilter.java @@ -19,22 +19,16 @@ import java.util.BitSet; import org.teavm.common.OptionalPredicate; class SuperClassFilter implements DependencyTypeFilter { - private static final int[] EMPTY_ARRAY = new int[0]; - private DependencyType superType; private OptionalPredicate predicate; private BitSet knownTypes = new BitSet(); private BitSet cache = new BitSet(); SuperClassFilter(DependencyAnalyzer dependencyAnalyzer, DependencyType superType) { - this.superType = superType; predicate = dependencyAnalyzer.getClassHierarchy().getSuperclassPredicate(superType.getName()); } @Override public boolean match(DependencyType type) { - if (!superType.subtypeExists) { - return superType.index == type.index; - } if (knownTypes.get(type.index)) { return cache.get(type.index); } @@ -43,12 +37,4 @@ class SuperClassFilter implements DependencyTypeFilter { cache.set(type.index, 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; - } }