mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Reduce memory consumption
This commit is contained in:
parent
6e416c11d7
commit
622006de0e
|
@ -42,7 +42,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
private DependencyNode arrayItemNode;
|
private DependencyNode arrayItemNode;
|
||||||
DependencyNode classValueNode;
|
DependencyNode classValueNode;
|
||||||
DependencyNode classNodeParent;
|
DependencyNode classNodeParent;
|
||||||
boolean classNodeComplete;
|
private boolean classNodeComplete;
|
||||||
int degree;
|
int degree;
|
||||||
boolean locked;
|
boolean locked;
|
||||||
MethodReference method;
|
MethodReference method;
|
||||||
|
@ -65,13 +65,13 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
propagateCount++;
|
propagateCount++;
|
||||||
moveToSeparateDomain();
|
moveToSeparateDomain();
|
||||||
typeSet.addType(type);
|
typeSet.addType(type);
|
||||||
scheduleSingleType(type, null);
|
scheduleSingleType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scheduleSingleType(DependencyType type, Runnable action) {
|
private void scheduleSingleType(DependencyType type) {
|
||||||
if (DependencyAnalyzer.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
for (DependencyNode node : typeSet.domain) {
|
for (DependencyNode node : typeSet.domain()) {
|
||||||
if (node.filter(type)) {
|
if (node.filter(type)) {
|
||||||
System.out.println(node.tag + " -> " + type.getName());
|
System.out.println(node.tag + " -> " + type.getName());
|
||||||
}
|
}
|
||||||
|
@ -81,10 +81,6 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
Transition[] transitions = typeSet.getTransitions().toArray(Transition.class);
|
Transition[] transitions = typeSet.getTransitions().toArray(Transition.class);
|
||||||
List<ConsumerWithNode> consumerEntries = typeSet.getConsumers();
|
List<ConsumerWithNode> consumerEntries = typeSet.getConsumers();
|
||||||
|
|
||||||
if (action != null) {
|
|
||||||
action.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Transition transition : transitions) {
|
for (Transition transition : transitions) {
|
||||||
if (transition.source.filter(type) && transition.filterType(type)) {
|
if (transition.source.filter(type) && transition.filterType(type)) {
|
||||||
dependencyAnalyzer.schedulePropagation(transition, type);
|
dependencyAnalyzer.schedulePropagation(transition, type);
|
||||||
|
@ -146,7 +142,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
|
|
||||||
void scheduleMultipleTypes(DependencyType[] newTypes, Runnable action) {
|
void scheduleMultipleTypes(DependencyType[] newTypes, Runnable action) {
|
||||||
if (DependencyAnalyzer.shouldLog) {
|
if (DependencyAnalyzer.shouldLog) {
|
||||||
for (DependencyNode node : typeSet.domain) {
|
for (var node : typeSet.domain()) {
|
||||||
for (DependencyType type : newTypes) {
|
for (DependencyType type : newTypes) {
|
||||||
if (node.filter(type)) {
|
if (node.filter(type)) {
|
||||||
System.out.println(node.tag + " -> " + type.getName());
|
System.out.println(node.tag + " -> " + type.getName());
|
||||||
|
@ -217,16 +213,6 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DeferredConsumerTypes {
|
|
||||||
final DependencyConsumer consumer;
|
|
||||||
final DependencyType[] types;
|
|
||||||
|
|
||||||
DeferredConsumerTypes(DependencyConsumer consumer, DependencyType[] types) {
|
|
||||||
this.consumer = consumer;
|
|
||||||
this.types = types;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean filter(DependencyType type) {
|
boolean filter(DependencyType type) {
|
||||||
if (typeFilter == null) {
|
if (typeFilter == null) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -282,7 +268,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean connectWithoutChildNodes(DependencyNode node, DependencyTypeFilter filter) {
|
private boolean connectWithoutChildNodes(DependencyNode node, DependencyTypeFilter filter) {
|
||||||
if (this == node) {
|
if (this == node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -467,7 +453,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
return i == result.length ? result : Arrays.copyOf(result, i);
|
return i == result.length ? result : Arrays.copyOf(result, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyType[] getTypesInternal(DependencyTypeFilter filter, DependencyNode sourceNode,
|
private DependencyType[] getTypesInternal(DependencyTypeFilter filter, DependencyNode sourceNode,
|
||||||
DependencyNode targetNode) {
|
DependencyNode targetNode) {
|
||||||
if (typeSet == null) {
|
if (typeSet == null) {
|
||||||
return TypeSet.EMPTY_TYPES;
|
return TypeSet.EMPTY_TYPES;
|
||||||
|
@ -487,7 +473,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
if (typeSet == null) {
|
if (typeSet == null) {
|
||||||
Collection<DependencyNode> domain = findDomain();
|
Collection<DependencyNode> domain = findDomain();
|
||||||
typeSet = new TypeSet(dependencyAnalyzer, this);
|
typeSet = new TypeSet(dependencyAnalyzer, this);
|
||||||
typeSet.domain.addAll(domain);
|
typeSet.addDomain(domain);
|
||||||
for (DependencyNode node : domain) {
|
for (DependencyNode node : domain) {
|
||||||
node.typeSet = typeSet;
|
node.typeSet = typeSet;
|
||||||
}
|
}
|
||||||
|
@ -503,11 +489,11 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typeSet.domain.removeAll(domain);
|
typeSet.removeDomain(domain);
|
||||||
typeSet.invalidate();
|
typeSet.invalidate();
|
||||||
|
|
||||||
typeSet = typeSet.copy(this);
|
typeSet = typeSet.copy(this);
|
||||||
typeSet.domain.addAll(domain);
|
typeSet.addDomain(domain);
|
||||||
|
|
||||||
for (DependencyNode node : domain) {
|
for (DependencyNode node : domain) {
|
||||||
node.typeSet = typeSet;
|
node.typeSet = typeSet;
|
||||||
|
@ -515,7 +501,7 @@ public class DependencyNode implements ValueDependencyInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<DependencyNode> findDomain() {
|
private Collection<DependencyNode> findDomain() {
|
||||||
if (!dependencyAnalyzer.domainOptimizationEnabled()) {
|
if (!dependencyAnalyzer.domainOptimizationEnabled()) {
|
||||||
return Collections.singleton(this);
|
return Collections.singleton(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.dependency;
|
||||||
|
|
||||||
import com.carrotsearch.hppc.IntHashSet;
|
import com.carrotsearch.hppc.IntHashSet;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
|
||||||
import org.teavm.model.ClassHierarchy;
|
import org.teavm.model.ClassHierarchy;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
|
||||||
|
@ -26,7 +25,7 @@ class Transition {
|
||||||
DependencyNode destination;
|
DependencyNode destination;
|
||||||
DependencyTypeFilter filter;
|
DependencyTypeFilter filter;
|
||||||
IntHashSet pendingTypes;
|
IntHashSet pendingTypes;
|
||||||
byte destSubsetOfSrc;
|
private byte destSubsetOfSrc;
|
||||||
|
|
||||||
Transition(DependencyNode source, DependencyNode destination, DependencyTypeFilter filter) {
|
Transition(DependencyNode source, DependencyNode destination, DependencyTypeFilter filter) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
@ -64,19 +63,19 @@ class Transition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mergeDomains(DependencyType[] types) {
|
private void mergeDomains(DependencyType[] types) {
|
||||||
destination.moveToSeparateDomain();
|
destination.moveToSeparateDomain();
|
||||||
destination.scheduleMultipleTypes(types, () -> {
|
destination.scheduleMultipleTypes(types, () -> {
|
||||||
Collection<DependencyNode> domainToMerge = destination.typeSet.domain;
|
var domainToMerge = destination.typeSet.domain();
|
||||||
for (DependencyNode node : domainToMerge) {
|
for (DependencyNode node : domainToMerge) {
|
||||||
node.typeSet = source.typeSet;
|
node.typeSet = source.typeSet;
|
||||||
source.typeSet.domain.add(node);
|
source.typeSet.addDomain(node);
|
||||||
}
|
}
|
||||||
source.typeSet.invalidate();
|
source.typeSet.invalidate();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean shouldMergeDomains() {
|
private boolean shouldMergeDomains() {
|
||||||
if (!source.dependencyAnalyzer.domainOptimizationEnabled() || filter != null || !isDestSubsetOfSrc()) {
|
if (!source.dependencyAnalyzer.domainOptimizationEnabled() || filter != null || !isDestSubsetOfSrc()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ import com.carrotsearch.hppc.cursors.ObjectCursor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
@ -34,14 +35,14 @@ class TypeSet {
|
||||||
private BitSet types;
|
private BitSet types;
|
||||||
private int typesCount;
|
private int typesCount;
|
||||||
|
|
||||||
Set<DependencyNode> domain = new LinkedHashSet<>();
|
private Object domain;
|
||||||
ObjectArrayList<Transition> transitions;
|
ObjectArrayList<Transition> transitions;
|
||||||
ArrayList<ConsumerWithNode> consumers;
|
ArrayList<ConsumerWithNode> consumers;
|
||||||
|
|
||||||
TypeSet(DependencyAnalyzer dependencyAnalyzer, DependencyNode origin) {
|
TypeSet(DependencyAnalyzer dependencyAnalyzer, DependencyNode origin) {
|
||||||
this.dependencyAnalyzer = dependencyAnalyzer;
|
this.dependencyAnalyzer = dependencyAnalyzer;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
domain.add(origin);
|
domain = origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addType(DependencyType type) {
|
void addType(DependencyType type) {
|
||||||
|
@ -210,10 +211,76 @@ class TypeSet {
|
||||||
consumers = null;
|
consumers = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set<? extends DependencyNode> domain() {
|
||||||
|
if (domain == null) {
|
||||||
|
return Set.of();
|
||||||
|
} else if (domain instanceof DependencyNode) {
|
||||||
|
return Set.of((DependencyNode) domain);
|
||||||
|
} else {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (Set<? extends DependencyNode>) domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDomain(DependencyNode node) {
|
||||||
|
if (domain == null) {
|
||||||
|
domain = node;
|
||||||
|
} else if (domain instanceof DependencyNode) {
|
||||||
|
if (domain == node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
domain = new HashSet<>(Set.of((DependencyNode) domain));
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var set = (Set<DependencyNode>) domain;
|
||||||
|
set.add(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addDomain(Collection<? extends DependencyNode> nodes) {
|
||||||
|
if (nodes.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (domain == null) {
|
||||||
|
if (nodes.size() == 1) {
|
||||||
|
domain = nodes.iterator().next();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (domain instanceof DependencyNode) {
|
||||||
|
if (nodes.contains(domain) && nodes.size() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
domain = new HashSet<>(Set.of((DependencyNode) domain));
|
||||||
|
}
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var set = (Set<DependencyNode>) domain;
|
||||||
|
set.addAll(nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeDomain(Collection<? extends DependencyNode> nodes) {
|
||||||
|
if (domain == null || nodes.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (domain instanceof DependencyNode) {
|
||||||
|
if (nodes.contains(domain)) {
|
||||||
|
domain = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var set = (Set<DependencyNode>) domain;
|
||||||
|
set.removeAll(nodes);
|
||||||
|
if (set.isEmpty()) {
|
||||||
|
domain = null;
|
||||||
|
} else if (set.size() == 1) {
|
||||||
|
domain = set.iterator().next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ObjectArrayList<Transition> getTransitions() {
|
ObjectArrayList<Transition> getTransitions() {
|
||||||
if (transitions == null) {
|
if (transitions == null) {
|
||||||
transitions = new ObjectArrayList<>(domain.size() * 2);
|
transitions = new ObjectArrayList<>();
|
||||||
for (DependencyNode node : domain) {
|
for (DependencyNode node : domain()) {
|
||||||
if (node.transitions != null) {
|
if (node.transitions != null) {
|
||||||
for (ObjectCursor<Transition> cursor : node.transitionList) {
|
for (ObjectCursor<Transition> cursor : node.transitionList) {
|
||||||
Transition transition = cursor.value;
|
Transition transition = cursor.value;
|
||||||
|
@ -230,7 +297,7 @@ class TypeSet {
|
||||||
List<ConsumerWithNode> getConsumers() {
|
List<ConsumerWithNode> getConsumers() {
|
||||||
if (consumers == null) {
|
if (consumers == null) {
|
||||||
consumers = new ArrayList<>();
|
consumers = new ArrayList<>();
|
||||||
for (DependencyNode node : domain) {
|
for (var node : domain()) {
|
||||||
if (node.followers != null) {
|
if (node.followers != null) {
|
||||||
consumers.add(new ConsumerWithNode(node.followers.toArray(new DependencyConsumer[0]), node));
|
consumers.add(new ConsumerWithNode(node.followers.toArray(new DependencyConsumer[0]), node));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
|
||||||
class VirtualCallConsumer implements DependencyConsumer {
|
class VirtualCallConsumer implements DependencyConsumer {
|
||||||
private static int SMALL_TYPES_THRESHOLD = 16;
|
private static final int SMALL_TYPES_THRESHOLD = 16;
|
||||||
private final MethodDescriptor methodDesc;
|
private final MethodDescriptor methodDesc;
|
||||||
private final DependencyAnalyzer analyzer;
|
private final DependencyAnalyzer analyzer;
|
||||||
private final DependencyNode[] parameters;
|
private final DependencyNode[] parameters;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user