Don't generate unused class names in metadata section

This commit is contained in:
Alexey Andreev 2018-10-03 14:46:52 +03:00
parent be21e474c5
commit 0a94c91ff2
8 changed files with 57 additions and 7 deletions

View File

@ -57,6 +57,12 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
private MethodReference forName = new MethodReference(Class.class, "forName", String.class, Boolean.class,
ClassLoader.class, Class.class);
private MethodReference forNameShort = new MethodReference(Class.class, "forName", String.class, Class.class);
private MethodReference fieldGetType = new MethodReference(Field.class, "getType", Class.class);
private MethodReference methodGetReturnType = new MethodReference(Method.class, "getReturnType", Class.class);
private MethodReference methodGetParameterTypes = new MethodReference(Method.class, "getParameterTypes",
Class[].class);
private MethodReference constructorGetParameterTypes = new MethodReference(Constructor.class, "getParameterTypes",
Class[].class);
private boolean fieldGetHandled;
private boolean fieldSetHandled;
private boolean newInstanceHandled;
@ -66,6 +72,7 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
private Set<String> classesWithReflectableFields = new LinkedHashSet<>();
private Set<String> classesWithReflectableMethods = new LinkedHashSet<>();
private DependencyNode allClasses;
private DependencyNode typesInReflectableSignaturesNode;
public ReflectionDependencyListener(List<ReflectionSupplier> reflectionSuppliers) {
this.reflectionSuppliers = reflectionSuppliers;
@ -74,6 +81,7 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
@Override
public void started(DependencyAgent agent) {
allClasses = agent.createNode();
typesInReflectableSignaturesNode = agent.createNode();
}
public Set<String> getClassesWithReflectableFields() {
@ -138,6 +146,13 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
});
} else if (method.getReference().equals(forName) || method.getReference().equals(forNameShort)) {
allClasses.connect(method.getResult().getClassValueNode());
} else if (method.getReference().equals(fieldGetType) || method.getReference().equals(methodGetReturnType)) {
method.getResult().propagate(agent.getType("java.lang.Class"));
typesInReflectableSignaturesNode.connect(method.getResult().getClassValueNode());
} else if (method.getReference().equals(methodGetParameterTypes)
|| method.getReference().equals(constructorGetParameterTypes)) {
method.getResult().getArrayItem().propagate(agent.getType("java.lang.Class"));
typesInReflectableSignaturesNode.connect(method.getResult().getArrayItem().getClassValueNode());
}
}
@ -251,7 +266,9 @@ public class ReflectionDependencyListener extends AbstractDependencyListener {
type = ((ValueType.Array) type).getItemType();
}
if (type instanceof ValueType.Object) {
agent.linkClass(((ValueType.Object) type).getClassName(), null);
String className = ((ValueType.Object) type).getClassName();
agent.linkClass(className, null);
typesInReflectableSignaturesNode.propagate(agent.getType(className));
}
}

View File

@ -80,6 +80,7 @@ public class TConstructor<T> extends TAccessibleObject implements TMember {
sb.append(' ');
}
sb.append(declaringClass.getName().toString()).append('(');
TClass<?>[] parameterTypes = getParameterTypes();
for (int i = 0; i < parameterTypes.length; ++i) {
if (i > 0) {
sb.append(',');

View File

@ -81,7 +81,7 @@ public class TField extends TAccessibleObject implements TMember {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append(type.getName()).append(' ').append(declaringClass.getName()).append(".").append(name);
sb.append(getType().getName()).append(' ').append(declaringClass.getName()).append(".").append(name);
return sb.toString();
}

View File

@ -80,8 +80,9 @@ public class TMethod extends TAccessibleObject implements TMember {
if (sb.length() > 0) {
sb.append(' ');
}
sb.append(returnType.getName()).append(' ').append(declaringClass.getName()).append('.')
sb.append(getReturnType().getName()).append(' ').append(declaringClass.getName()).append('.')
.append(name).append('(');
TClass<?>[] parameterTypes = getParameterTypes();
if (parameterTypes.length > 0) {
sb.append(parameterTypes[0].getName());
for (int i = 1; i < parameterTypes.length; ++i) {

View File

@ -266,7 +266,8 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
}
RenderingContext renderingContext = new RenderingContext(debugEmitterToUse,
controller.getUnprocessedClassSource(), classes,
controller.getClassLoader(), controller.getServices(), controller.getProperties(), naming);
controller.getClassLoader(), controller.getServices(), controller.getProperties(), naming,
controller.getDependencyInfo());
renderingContext.setMinifying(minifying);
Renderer renderer = new Renderer(sourceWriter, asyncMethods, asyncFamilyMethods,
controller.getDiagnostics(), renderingContext);

View File

@ -19,6 +19,7 @@ import com.carrotsearch.hppc.ObjectIntHashMap;
import com.carrotsearch.hppc.ObjectIntMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
@ -41,6 +42,7 @@ import org.teavm.backend.javascript.spi.GeneratorContext;
import org.teavm.common.ServiceRepository;
import org.teavm.debugging.information.DebugInformationEmitter;
import org.teavm.debugging.information.DummyDebugInformationEmitter;
import org.teavm.dependency.MethodDependencyInfo;
import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource;
@ -485,6 +487,19 @@ public class Renderer implements RenderingManager {
}
private void renderClassMetadata(List<ClassNode> classes) {
Set<String> classesRequiringName = new HashSet<>();
MethodDependencyInfo getNameMethod = context.getDependencyInfo().getMethod(
new MethodReference(Class.class, "getName", String.class));
if (getNameMethod != null) {
classesRequiringName.addAll(Arrays.asList(getNameMethod.getVariable(0).getClassValueNode().getTypes()));
}
MethodDependencyInfo getSimpleNameMethod = context.getDependencyInfo().getMethod(
new MethodReference(Class.class, "getSimpleName", String.class));
if (getSimpleNameMethod != null) {
classesRequiringName.addAll(Arrays.asList(
getSimpleNameMethod.getVariable(0).getClassValueNode().getTypes()));
}
int start = writer.getOffset();
try {
writer.append("$rt_metadata([");
@ -495,7 +510,14 @@ public class Renderer implements RenderingManager {
}
first = false;
writer.appendClass(cls.getName()).append(",").ws();
writer.append("\"").append(RenderingUtil.escapeString(cls.getName())).append("\",").ws();
if (classesRequiringName.contains(cls.getName())) {
writer.append("\"").append(RenderingUtil.escapeString(cls.getName())).append("\"");
} else {
writer.append("0");
}
writer.append(",").ws();
if (cls.getParentName() != null) {
writer.appendClass(cls.getParentName());
} else {

View File

@ -30,6 +30,7 @@ import org.teavm.backend.javascript.spi.InjectedBy;
import org.teavm.backend.javascript.spi.Injector;
import org.teavm.common.ServiceRepository;
import org.teavm.debugging.information.DebugInformationEmitter;
import org.teavm.dependency.DependencyInfo;
import org.teavm.interop.PlatformMarker;
import org.teavm.model.AnnotationReader;
import org.teavm.model.ClassReader;
@ -48,6 +49,7 @@ public class RenderingContext {
private ServiceRepository services;
private Properties properties;
private NamingStrategy naming;
private DependencyInfo dependencyInfo;
private final Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
private final Map<String, Integer> stringPoolMap = new HashMap<>();
private final List<String> stringPool = new ArrayList<>();
@ -58,7 +60,7 @@ public class RenderingContext {
public RenderingContext(DebugInformationEmitter debugEmitter,
ClassReaderSource initialClassSource, ListableClassReaderSource classSource,
ClassLoader classLoader, ServiceRepository services, Properties properties,
NamingStrategy naming) {
NamingStrategy naming, DependencyInfo dependencyInfo) {
this.debugEmitter = debugEmitter;
this.initialClassSource = initialClassSource;
this.classSource = classSource;
@ -66,6 +68,7 @@ public class RenderingContext {
this.services = services;
this.properties = properties;
this.naming = naming;
this.dependencyInfo = dependencyInfo;
}
public ClassReaderSource getInitialClassSource() {
@ -92,6 +95,10 @@ public class RenderingContext {
return naming;
}
public DependencyInfo getDependencyInfo() {
return dependencyInfo;
}
public void setMinifying(boolean minifying) {
this.minifying = minifying;
}

View File

@ -433,7 +433,8 @@ function $rt_metadata(data) {
var cls = data[i];
cls.$meta = {};
var m = cls.$meta;
m.name = data[i + 1];
var className = data[i + 1];
m.name = className !== 0 ? className : null;
m.binaryName = "L" + m.name + ";";
var superclass = data[i + 2];
m.superclass = superclass !== 0 ? superclass : null;