mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Trying to decrease compiler memory consumption
This commit is contained in:
parent
84b4133989
commit
2c40c7d56e
|
@ -41,11 +41,11 @@ import org.teavm.dependency.MethodDependency;
|
|||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
public class ServiceLoaderSupport extends AbstractDependencyListener implements Generator {
|
||||
private static final MethodReference LOAD_METHOD = new MethodReference(ServiceLoader.class, "load", Class.class,
|
||||
ServiceLoader.class);
|
||||
private static final MethodDescriptor INIT_METHOD = new MethodDescriptor("<init>", void.class);
|
||||
private Map<String, List<String>> serviceMap = new HashMap<>();
|
||||
private ClassLoader classLoader;
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class ServiceLoaderSupport extends AbstractDependencyListener implements
|
|||
String implName = implementations.get(i);
|
||||
if (context.getClassSource().getClassNames().contains(implName)) {
|
||||
writer.append("[").appendClass(implName).append(", ").appendMethodBody(
|
||||
new MethodReference(implName, new MethodDescriptor("<init>", ValueType.VOID)))
|
||||
new MethodReference(implName, INIT_METHOD))
|
||||
.append("]");
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +105,7 @@ public class ServiceLoaderSupport extends AbstractDependencyListener implements
|
|||
}
|
||||
serviceMap.computeIfAbsent(type.getName(), k -> new ArrayList<>()).add(implementationType);
|
||||
|
||||
MethodReference ctor = new MethodReference(implementationType,
|
||||
new MethodDescriptor("<init>", ValueType.VOID));
|
||||
MethodReference ctor = new MethodReference(implementationType, INIT_METHOD);
|
||||
agent.linkMethod(ctor).addLocation(location).use();
|
||||
method.getResult().getArrayItem().propagate(agent.getType(implementationType));
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.teavm.classlib.impl.lambda;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -29,6 +30,7 @@ import org.teavm.model.ClassReader;
|
|||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldHolder;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodHandle;
|
||||
import org.teavm.model.MethodHandleType;
|
||||
import org.teavm.model.MethodHolder;
|
||||
|
@ -46,6 +48,8 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
private static final int FLAG_MARKERS = 2;
|
||||
private static final int FLAG_BRIDGES = 4;
|
||||
private Map<MethodReference, Integer> lambdaIdsByMethod = new HashMap<>();
|
||||
private Map<MethodDescriptor, MethodDescriptor> descriptorCache = new HashMap<>();
|
||||
private List<String> fieldNameCache = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public ValueEmitter substitute(DynamicCallSite callSite, ProgramEmitter callerPe) {
|
||||
|
@ -100,7 +104,7 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
ValueType[] implementorSignature = getSignature(implMethod);
|
||||
ValueEmitter[] passedArguments = new ValueEmitter[implementorSignature.length - 1];
|
||||
for (int i = 0; i < capturedVarCount; ++i) {
|
||||
passedArguments[i] = thisVar.getField("_" + i, invokedType[i]);
|
||||
passedArguments[i] = thisVar.getField(fieldName(i), invokedType[i]);
|
||||
}
|
||||
for (int i = 0; i < instantiatedMethodType.length - 1; ++i) {
|
||||
passedArguments[i + capturedVarCount] = tryConvertArgument(arguments[i], instantiatedMethodType[i],
|
||||
|
@ -298,7 +302,9 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
TextLocation location) {
|
||||
ValueType[] signature = Arrays.copyOf(types, types.length + 1);
|
||||
signature[types.length] = ValueType.VOID;
|
||||
MethodHolder ctor = new MethodHolder("<init>", signature);
|
||||
MethodDescriptor descriptor = descriptorCache.computeIfAbsent(new MethodDescriptor("<init>", signature),
|
||||
k -> k);
|
||||
MethodHolder ctor = new MethodHolder(descriptor);
|
||||
ctor.setLevel(AccessLevel.PUBLIC);
|
||||
|
||||
ProgramEmitter pe = ProgramEmitter.create(ctor, hierarchy);
|
||||
|
@ -307,7 +313,7 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
thisVar.invokeSpecial(implementor.getParent(), "<init>");
|
||||
|
||||
for (int i = 0; i < types.length; ++i) {
|
||||
FieldHolder field = new FieldHolder("_" + i);
|
||||
FieldHolder field = new FieldHolder(fieldName(i));
|
||||
field.setLevel(AccessLevel.PRIVATE);
|
||||
field.setType(types[i]);
|
||||
implementor.addField(field);
|
||||
|
@ -319,6 +325,18 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
|
|||
return ctor;
|
||||
}
|
||||
|
||||
private String fieldName(int index) {
|
||||
if (index >= fieldNameCache.size()) {
|
||||
fieldNameCache.addAll(Collections.nCopies(index - fieldNameCache.size() + 1, null));
|
||||
}
|
||||
String result = fieldNameCache.get(index);
|
||||
if (result == null) {
|
||||
result = "_" + index;
|
||||
fieldNameCache.set(index, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void createBridge(ClassHierarchy hierarchy, ClassHolder implementor, String name, ValueType[] types,
|
||||
ValueType[] bridgeTypes, TextLocation location) {
|
||||
if (Arrays.equals(types, bridgeTypes)) {
|
||||
|
|
|
@ -59,6 +59,7 @@ class NameFrequencyEstimator extends RecursiveVisitor implements MethodNodeVisit
|
|||
"monitorExit", Object.class, void.class);
|
||||
static final MethodReference MONITOR_EXIT_SYNC_METHOD = new MethodReference(Object.class,
|
||||
"monitorExitSync", Object.class, void.class);
|
||||
private static final MethodDescriptor CLINIT_METHOD = new MethodDescriptor("<clinit>", ValueType.VOID);
|
||||
|
||||
private final NameFrequencyConsumer consumer;
|
||||
private final ClassReaderSource classSource;
|
||||
|
@ -88,8 +89,7 @@ class NameFrequencyEstimator extends RecursiveVisitor implements MethodNodeVisit
|
|||
}
|
||||
|
||||
// Methods
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(
|
||||
new MethodDescriptor("<clinit>", ValueType.VOID));
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(CLINIT_METHOD);
|
||||
for (PreparedMethod method : cls.getMethods()) {
|
||||
consumer.consume(method.reference);
|
||||
if (asyncFamilyMethods.contains(method.reference)) {
|
||||
|
|
|
@ -76,6 +76,7 @@ public class Renderer implements RenderingManager {
|
|||
private RenderingContext context;
|
||||
private List<PostponedFieldInitializer> postponedFieldInitializers = new ArrayList<>();
|
||||
private IntFunction<TeaVMProgressFeedback> progressConsumer = p -> TeaVMProgressFeedback.CONTINUE;
|
||||
private static final MethodDescriptor CLINIT_METHOD = new MethodDescriptor("<clinit>", ValueType.VOID);
|
||||
|
||||
private ObjectIntMap<String> sizeByClass = new ObjectIntHashMap<>();
|
||||
private int stringPoolSize;
|
||||
|
@ -376,8 +377,7 @@ public class Renderer implements RenderingManager {
|
|||
private void renderMethodBodies(PreparedClass cls) throws RenderingException {
|
||||
debugEmitter.emitClass(cls.getName());
|
||||
try {
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(
|
||||
new MethodDescriptor("<clinit>", ValueType.VOID));
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(CLINIT_METHOD);
|
||||
|
||||
if (clinit != null) {
|
||||
renderCallClinit(clinit, cls);
|
||||
|
@ -540,8 +540,7 @@ public class Renderer implements RenderingManager {
|
|||
writer.append(ElementModifier.pack(cls.getClassHolder().getModifiers())).append(',').ws();
|
||||
writer.append(cls.getClassHolder().getLevel().ordinal()).append(',').ws();
|
||||
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(
|
||||
new MethodDescriptor("<clinit>", ValueType.VOID));
|
||||
MethodReader clinit = classSource.get(cls.getName()).getMethod(CLINIT_METHOD);
|
||||
if (clinit != null) {
|
||||
writer.appendClassInit(cls.getName());
|
||||
} else {
|
||||
|
|
|
@ -103,6 +103,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
|||
private List<String> blockIds = new ArrayList<>();
|
||||
private IntIndexedContainer blockIndexMap = new IntArrayList();
|
||||
private boolean longLibraryUsed;
|
||||
private static final MethodDescriptor CLINIT_METHOD = new MethodDescriptor("<clinit>", ValueType.VOID);
|
||||
|
||||
public StatementRenderer(RenderingContext context, SourceWriter writer) {
|
||||
this.context = context;
|
||||
|
@ -462,7 +463,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
|
|||
if (cls == null) {
|
||||
return;
|
||||
}
|
||||
MethodReader method = cls.getMethod(new MethodDescriptor("<clinit>", void.class));
|
||||
MethodReader method = cls.getMethod(CLINIT_METHOD);
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.Serializable;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
@ -33,8 +34,8 @@ import org.teavm.model.FieldReference;
|
|||
import org.teavm.model.MethodReference;
|
||||
|
||||
public class DefaultCallGraph implements CallGraph, Serializable {
|
||||
Map<MethodReference, DefaultCallGraphNode> nodes = new LinkedHashMap<>();
|
||||
Map<FieldReference, Set<DefaultFieldAccessSite>> fieldAccessSites = new LinkedHashMap<>();
|
||||
public Map<MethodReference, DefaultCallGraphNode> nodes = new HashMap<>();
|
||||
Map<FieldReference, Set<DefaultFieldAccessSite>> fieldAccessSites = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public DefaultCallGraphNode getNode(MethodReference method) {
|
||||
|
|
|
@ -28,9 +28,11 @@ import org.teavm.model.TextLocation;
|
|||
public class DefaultCallGraphNode implements CallGraphNode {
|
||||
private DefaultCallGraph graph;
|
||||
private MethodReference method;
|
||||
private Set<DefaultCallSite> callSites = new LinkedHashSet<>(10, 0.5f);
|
||||
private Set<DefaultCallSite> callSites;
|
||||
private DefaultCallSite singleCallSite;
|
||||
private Set<DefaultCallSite> safeCallSites;
|
||||
private List<DefaultCallSite> callerCallSites = new ArrayList<>();
|
||||
private DefaultCallSite singleCaller;
|
||||
private List<DefaultCallSite> callerCallSites;
|
||||
private List<DefaultCallSite> safeCallersCallSites;
|
||||
private Set<DefaultFieldAccessSite> fieldAccessSites = new LinkedHashSet<>();
|
||||
private Set<DefaultFieldAccessSite> safeFieldAccessSites;
|
||||
|
@ -52,6 +54,12 @@ public class DefaultCallGraphNode implements CallGraphNode {
|
|||
|
||||
@Override
|
||||
public Collection<DefaultCallSite> getCallSites() {
|
||||
if (callSites == null) {
|
||||
if (singleCallSite != null) {
|
||||
return Collections.singletonList(singleCallSite);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (safeCallSites == null) {
|
||||
safeCallSites = Collections.unmodifiableSet(callSites);
|
||||
}
|
||||
|
@ -60,6 +68,12 @@ public class DefaultCallGraphNode implements CallGraphNode {
|
|||
|
||||
@Override
|
||||
public Collection<DefaultCallSite> getCallerCallSites() {
|
||||
if (callerCallSites == null) {
|
||||
if (singleCaller != null) {
|
||||
return Collections.singletonList(singleCaller);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (safeCallersCallSites == null) {
|
||||
safeCallersCallSites = Collections.unmodifiableList(callerCallSites);
|
||||
}
|
||||
|
@ -69,14 +83,37 @@ public class DefaultCallGraphNode implements CallGraphNode {
|
|||
public boolean addCallSite(MethodReference method, TextLocation location) {
|
||||
DefaultCallGraphNode callee = graph.getNode(method);
|
||||
DefaultCallSite callSite = new DefaultCallSite(location, callee, this);
|
||||
if (callSites == null) {
|
||||
if (singleCallSite == null) {
|
||||
singleCallSite = callSite;
|
||||
callee.addCaller(callSite);
|
||||
return true;
|
||||
}
|
||||
callSites = new LinkedHashSet<>();
|
||||
callSites.add(singleCallSite);
|
||||
singleCallSite = null;
|
||||
}
|
||||
if (callSites.add(callSite)) {
|
||||
callee.callerCallSites.add(callSite);
|
||||
callee.addCaller(callSite);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void addCaller(DefaultCallSite caller) {
|
||||
if (callerCallSites == null) {
|
||||
if (singleCaller == null) {
|
||||
singleCaller = caller;
|
||||
return;
|
||||
}
|
||||
callerCallSites = new ArrayList<>();
|
||||
callerCallSites.add(singleCaller);
|
||||
singleCaller = null;
|
||||
}
|
||||
callerCallSites.add(caller);
|
||||
}
|
||||
|
||||
public boolean addCallSite(MethodReference method) {
|
||||
return addCallSite(method, null);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public class ReferenceCache {
|
|||
public MethodReference getCached(String className, MethodDescriptor descriptor) {
|
||||
return referenceCache
|
||||
.computeIfAbsent(className, key -> new HashMap<>())
|
||||
.computeIfAbsent(descriptor, key -> new MethodReference(className, descriptor));
|
||||
.computeIfAbsent(getCached(descriptor), key -> new MethodReference(className, key));
|
||||
}
|
||||
|
||||
public MethodDescriptor getCached(MethodDescriptor descriptor) {
|
||||
|
|
|
@ -17,8 +17,11 @@ package org.teavm.model.emit;
|
|||
|
||||
import org.teavm.model.BasicBlock;
|
||||
import org.teavm.model.ClassHierarchy;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.Incoming;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Phi;
|
||||
import org.teavm.model.PrimitiveType;
|
||||
|
@ -467,7 +470,11 @@ public class ValueEmitter {
|
|||
}
|
||||
signature[arguments.length] = resultType;
|
||||
|
||||
MethodReference method = new MethodReference(className, name, signature);
|
||||
ClassReader cls = pe.classSource.get(className);
|
||||
MethodReader methodReader = cls != null ? cls.getMethod(new MethodDescriptor(name, signature)) : null;
|
||||
MethodReference method = methodReader != null
|
||||
? methodReader.getReference()
|
||||
: new MethodReference(className, name, signature);
|
||||
if (method.getReturnType() != ValueType.VOID) {
|
||||
result = pe.getProgram().createVariable();
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ public class AsyncProgramSplitter {
|
|||
private ClassReaderSource classSource;
|
||||
private Set<MethodReference> asyncMethods;
|
||||
private Program program;
|
||||
private static final MethodDescriptor CLINIT_METHOD = new MethodDescriptor("<clinit>", ValueType.VOID);
|
||||
|
||||
public AsyncProgramSplitter(ClassReaderSource classSource, Set<MethodReference> asyncMethods) {
|
||||
this.classSource = classSource;
|
||||
|
@ -211,7 +212,7 @@ public class AsyncProgramSplitter {
|
|||
return false;
|
||||
}
|
||||
|
||||
MethodReader method = cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID));
|
||||
MethodReader method = cls.getMethod(CLINIT_METHOD);
|
||||
return method != null && asyncMethods.contains(method.getReference());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.teavm.model.InvokeDynamicInstruction;
|
|||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodHandle;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.ReferenceCache;
|
||||
import org.teavm.model.RuntimeConstant;
|
||||
|
@ -108,7 +107,8 @@ public class ClassRefsRenamer extends AbstractInstructionVisitor {
|
|||
for (int i = 0; i < signature.length; ++i) {
|
||||
signature[i] = rename(signature[i]);
|
||||
}
|
||||
MethodHolder renamedMethod = new MethodHolder(methodName, signature);
|
||||
MethodHolder renamedMethod = new MethodHolder(referenceCache.getCached(
|
||||
new MethodDescriptor(methodName, signature)));
|
||||
renamedMethod.getModifiers().addAll(method.getModifiers());
|
||||
renamedMethod.setLevel(method.getLevel());
|
||||
renamedMethod.setProgram(method.getProgram());
|
||||
|
@ -274,8 +274,8 @@ public class ClassRefsRenamer extends AbstractInstructionVisitor {
|
|||
signature[i] = newType;
|
||||
}
|
||||
if (changed) {
|
||||
insn.setMethod(referenceCache.getCached(new MethodReference(className,
|
||||
new MethodDescriptor(insn.getMethod().getName(), signature))));
|
||||
insn.setMethod(referenceCache.getCached(className,
|
||||
new MethodDescriptor(insn.getMethod().getName(), signature)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -463,6 +463,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
return null;
|
||||
}
|
||||
|
||||
dependencyAnalyzer.cleanup();
|
||||
|
||||
return classSet;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.model.BasicBlock;
|
|||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHolder;
|
||||
import org.teavm.model.FieldHolder;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Program;
|
||||
|
@ -43,6 +44,7 @@ public class ProxyVariableContext extends VariableContext {
|
|||
private int suffixGenerator;
|
||||
private Map<Variable, CapturedValue> capturedValueMap = new HashMap<>();
|
||||
private List<CapturedValue> capturedValues = new ArrayList<>();
|
||||
private static final MethodDescriptor INIT_METHOD = new MethodDescriptor("<init>", ValueType.VOID);
|
||||
|
||||
public ProxyVariableContext(VariableContext parent, ClassHolder proxyClass) {
|
||||
super(parent);
|
||||
|
@ -103,7 +105,7 @@ public class ProxyVariableContext extends VariableContext {
|
|||
|
||||
InvokeInstruction invokeSuper = new InvokeInstruction();
|
||||
invokeSuper.setInstance(ctorProgram.createVariable());
|
||||
invokeSuper.setMethod(new MethodReference(proxyClass.getParent(), "<init>", ValueType.VOID));
|
||||
invokeSuper.setMethod(new MethodReference(proxyClass.getParent(), INIT_METHOD));
|
||||
invokeSuper.setType(InvocationType.SPECIAL);
|
||||
ctorBlock.add(invokeSuper);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user