From f88b868c3928e2c1367b16845b66696f3207838c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 18 Nov 2013 17:28:02 +0400 Subject: [PATCH] Dependency checker now cuts off unused methods --- .../classlibgen/ClasslibTestGenerator.java | 6 +++++- .../teavm/dependency/DependencyChecker.java | 20 +++++++++++++++++++ .../java/org/teavm/model/ClassHolder.java | 8 -------- .../model/ListableClassHolderSource.java | 11 ++++++++++ .../teavm/model/MutableClassHolderSource.java | 8 +++++++- 5 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/model/ListableClassHolderSource.java diff --git a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java index 5faa6da8a..228b81642 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java @@ -41,12 +41,16 @@ public class ClasslibTestGenerator { renderer = new Renderer(writer, classSource); DependencyChecker dependencyChecker = new DependencyChecker(classSource); for (String testClass : testClasses) { - findTests(classSource.getClassHolder(testClass)); + ClassHolder classHolder = classSource.getClassHolder(testClass); + findTests(classHolder); + MethodReference cons = new MethodReference(testClass, new MethodDescriptor("", ValueType.VOID)); + dependencyChecker.addEntryPoint(cons); } for (MethodReference methodRef : testMethods) { dependencyChecker.addEntryPoint(methodRef); } dependencyChecker.checkDependencies(); + dependencyChecker.cutUnachievableClasses(); for (String className : dependencyChecker.getAchievableClasses()) { decompileClass(className); } diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 7464b7dd7..e767d6fca 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -235,4 +235,24 @@ public class DependencyChecker { } plugin.methodAchieved(this, methodRef); } + + public ListableClassHolderSource cutUnachievableClasses() { + MutableClassHolderSource cutClasses = new MutableClassHolderSource(); + for (String className : achievableClasses.keySet()) { + ClassHolder classHolder = classSource.getClassHolder(className); + for (MethodHolder method : classHolder.getMethods().toArray(new MethodHolder[0])) { + MethodReference methodRef = new MethodReference(className, method.getDescriptor()); + if (!methodCache.getCachedPreimages().contains(methodRef)) { + classHolder.removeMethod(method); + } + } + for (FieldHolder field : classHolder.getFields().toArray(new FieldHolder[0])) { + FieldReference fieldRef = new FieldReference(className, field.getName()); + if (!fieldCache.getCachedPreimages().contains(fieldRef)) { + classHolder.removeField(field); + } + } + } + return cutClasses; + } } diff --git a/teavm-core/src/main/java/org/teavm/model/ClassHolder.java b/teavm-core/src/main/java/org/teavm/model/ClassHolder.java index 80261cd45..6f275dcf8 100644 --- a/teavm-core/src/main/java/org/teavm/model/ClassHolder.java +++ b/teavm-core/src/main/java/org/teavm/model/ClassHolder.java @@ -64,10 +64,6 @@ public class ClassHolder extends ElementHolder { } public void removeMethod(MethodHolder method) { - if (method.getOwner() != null) { - throw new IllegalArgumentException("Method " + method.getDescriptor() + - " is not a member of " + getName()); - } if (method.getOwner() != this) { throw new IllegalArgumentException("Method " + method.getOwner().getName() + "." + method.getDescriptor() + " is not a member of " + getName()); @@ -97,10 +93,6 @@ public class ClassHolder extends ElementHolder { } public void removeField(FieldHolder field) { - if (field.getOwner() != null) { - throw new IllegalArgumentException("Field " + field.getName() + - " is not a member of " + getName()); - } if (field.getOwner() != this) { throw new IllegalArgumentException("Field " + field.getOwner().getName() + "." + field.getName() + " is not a member of " + getName()); diff --git a/teavm-core/src/main/java/org/teavm/model/ListableClassHolderSource.java b/teavm-core/src/main/java/org/teavm/model/ListableClassHolderSource.java new file mode 100644 index 000000000..3199062fe --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/model/ListableClassHolderSource.java @@ -0,0 +1,11 @@ +package org.teavm.model; + +import java.util.Set; + +/** + * + * @author Alexey Andreev + */ +public interface ListableClassHolderSource extends ClassHolderSource { + Set getClassNames(); +} diff --git a/teavm-core/src/main/java/org/teavm/model/MutableClassHolderSource.java b/teavm-core/src/main/java/org/teavm/model/MutableClassHolderSource.java index 6248e84c1..2d55eb390 100644 --- a/teavm-core/src/main/java/org/teavm/model/MutableClassHolderSource.java +++ b/teavm-core/src/main/java/org/teavm/model/MutableClassHolderSource.java @@ -15,6 +15,7 @@ */ package org.teavm.model; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -22,9 +23,14 @@ import java.util.concurrent.ConcurrentMap; * * @author Alexey Andreev */ -public class MutableClassHolderSource implements ClassHolderSource { +public class MutableClassHolderSource implements ListableClassHolderSource { private ConcurrentMap classes = new ConcurrentHashMap<>(); + @Override + public Set getClassNames() { + return classes.keySet(); + } + @Override public ClassHolder getClassHolder(String name) { return classes.get(name);