Use shared ReferenceCache between different stages of compilation

This commit is contained in:
Alexey Andreev 2019-03-05 19:32:50 +03:00
parent 3c9a3bb359
commit 2a1aca98da
25 changed files with 111 additions and 57 deletions

View File

@ -24,6 +24,7 @@ import java.util.jar.JarInputStream;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.teavm.model.ReferenceCache;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
public class JCLComparisonBuilder { public class JCLComparisonBuilder {
@ -119,7 +120,7 @@ public class JCLComparisonBuilder {
if (!path.startsWith(JAR_PREFIX) || !path.endsWith(JAR_SUFFIX)) { if (!path.startsWith(JAR_PREFIX) || !path.endsWith(JAR_SUFFIX)) {
throw new RuntimeException("Can't find JCL classes"); throw new RuntimeException("Can't find JCL classes");
} }
ClasspathClassHolderSource classSource = new ClasspathClassHolderSource(classLoader); ClasspathClassHolderSource classSource = new ClasspathClassHolderSource(classLoader, new ReferenceCache());
path = path.substring(JAR_PREFIX.length(), path.length() - JAR_SUFFIX.length()); path = path.substring(JAR_PREFIX.length(), path.length() - JAR_SUFFIX.length());
File outDir = new File(outputDirectory).getParentFile(); File outDir = new File(outputDirectory).getParentFile();
if (!outDir.exists()) { if (!outDir.exists()) {

View File

@ -83,9 +83,10 @@ public class AstIO {
private final SymbolTable symbolTable; private final SymbolTable symbolTable;
private final SymbolTable fileTable; private final SymbolTable fileTable;
private final Map<String, IdentifiedStatement> statementMap = new HashMap<>(); private final Map<String, IdentifiedStatement> statementMap = new HashMap<>();
private ReferenceCache referenceCache = new ReferenceCache(); private ReferenceCache referenceCache;
public AstIO(SymbolTable symbolTable, SymbolTable fileTable) { public AstIO(ReferenceCache referenceCache, SymbolTable symbolTable, SymbolTable fileTable) {
this.referenceCache = referenceCache;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.fileTable = fileTable; this.fileTable = fileTable;
} }

View File

@ -48,6 +48,7 @@ import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodHolder; import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ReferenceCache;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.parsing.ClassDateProvider; import org.teavm.parsing.ClassDateProvider;
@ -62,13 +63,13 @@ public class DiskCachedClassHolderSource implements ClassHolderSource, CacheStat
private Set<String> newClasses = new HashSet<>(); private Set<String> newClasses = new HashSet<>();
private ProgramIO programIO; private ProgramIO programIO;
public DiskCachedClassHolderSource(File directory, SymbolTable symbolTable, SymbolTable fileTable, public DiskCachedClassHolderSource(File directory, ReferenceCache referenceCache, SymbolTable symbolTable,
ClassHolderSource innerSource, ClassDateProvider classDateProvider) { SymbolTable fileTable, ClassHolderSource innerSource, ClassDateProvider classDateProvider) {
this.directory = directory; this.directory = directory;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.innerSource = innerSource; this.innerSource = innerSource;
this.classDateProvider = classDateProvider; this.classDateProvider = classDateProvider;
programIO = new ProgramIO(symbolTable, fileTable); programIO = new ProgramIO(referenceCache, symbolTable, fileTable);
} }
@Override @Override

View File

@ -31,6 +31,7 @@ import org.teavm.ast.AsyncMethodNode;
import org.teavm.ast.ControlFlowEntry; import org.teavm.ast.ControlFlowEntry;
import org.teavm.ast.RegularMethodNode; import org.teavm.ast.RegularMethodNode;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ReferenceCache;
public class DiskMethodNodeCache implements MethodNodeCache { public class DiskMethodNodeCache implements MethodNodeCache {
private final File directory; private final File directory;
@ -40,9 +41,10 @@ public class DiskMethodNodeCache implements MethodNodeCache {
private final Set<MethodReference> newMethods = new HashSet<>(); private final Set<MethodReference> newMethods = new HashSet<>();
private final Set<MethodReference> newAsyncMethods = new HashSet<>(); private final Set<MethodReference> newAsyncMethods = new HashSet<>();
public DiskMethodNodeCache(File directory, SymbolTable symbolTable, SymbolTable fileTable) { public DiskMethodNodeCache(File directory, ReferenceCache referenceCache, SymbolTable symbolTable,
SymbolTable fileTable) {
this.directory = directory; this.directory = directory;
astIO = new AstIO(symbolTable, fileTable); astIO = new AstIO(referenceCache, symbolTable, fileTable);
} }
@Override @Override

View File

@ -37,6 +37,7 @@ import org.teavm.model.ClassReaderSource;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ProgramCache; import org.teavm.model.ProgramCache;
import org.teavm.model.ReferenceCache;
public class DiskProgramCache implements ProgramCache { public class DiskProgramCache implements ProgramCache {
private File directory; private File directory;
@ -44,9 +45,10 @@ public class DiskProgramCache implements ProgramCache {
private Map<MethodReference, Item> cache = new HashMap<>(); private Map<MethodReference, Item> cache = new HashMap<>();
private Set<MethodReference> newMethods = new HashSet<>(); private Set<MethodReference> newMethods = new HashSet<>();
public DiskProgramCache(File directory, SymbolTable symbolTable, SymbolTable fileTable) { public DiskProgramCache(File directory, ReferenceCache referenceCache, SymbolTable symbolTable,
SymbolTable fileTable) {
this.directory = directory; this.directory = directory;
programIO = new ProgramIO(symbolTable, fileTable); programIO = new ProgramIO(referenceCache, symbolTable, fileTable);
} }
@Override @Override

View File

@ -26,6 +26,7 @@ import org.teavm.ast.AsyncMethodNode;
import org.teavm.ast.ControlFlowEntry; import org.teavm.ast.ControlFlowEntry;
import org.teavm.ast.RegularMethodNode; import org.teavm.ast.RegularMethodNode;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ReferenceCache;
public class InMemoryMethodNodeCache implements MethodNodeCache { public class InMemoryMethodNodeCache implements MethodNodeCache {
private Map<MethodReference, RegularItem> cache = new HashMap<>(); private Map<MethodReference, RegularItem> cache = new HashMap<>();
@ -34,8 +35,9 @@ public class InMemoryMethodNodeCache implements MethodNodeCache {
private Map<MethodReference, AsyncItem> newAsyncItems = new HashMap<>(); private Map<MethodReference, AsyncItem> newAsyncItems = new HashMap<>();
private AstIO io; private AstIO io;
public InMemoryMethodNodeCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) { public InMemoryMethodNodeCache(ReferenceCache referenceCache, InMemorySymbolTable symbolTable,
io = new AstIO(symbolTable, fileSymbolTable); InMemorySymbolTable fileSymbolTable) {
io = new AstIO(referenceCache, symbolTable, fileSymbolTable);
} }
@Override @Override

View File

@ -25,14 +25,16 @@ import java.util.function.Supplier;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ProgramCache; import org.teavm.model.ProgramCache;
import org.teavm.model.ReferenceCache;
public class InMemoryProgramCache implements ProgramCache { public class InMemoryProgramCache implements ProgramCache {
private Map<MethodReference, Item> cache = new HashMap<>(); private Map<MethodReference, Item> cache = new HashMap<>();
private Map<MethodReference, Item> newItems = new HashMap<>(); private Map<MethodReference, Item> newItems = new HashMap<>();
private ProgramIO io; private ProgramIO io;
public InMemoryProgramCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) { public InMemoryProgramCache(ReferenceCache referenceCache, InMemorySymbolTable symbolTable,
io = new ProgramIO(symbolTable, fileSymbolTable); InMemorySymbolTable fileSymbolTable) {
io = new ProgramIO(referenceCache, symbolTable, fileSymbolTable);
} }
@Override @Override

View File

@ -85,7 +85,7 @@ import org.teavm.model.instructions.UnwrapArrayInstruction;
public class ProgramIO { public class ProgramIO {
private SymbolTable symbolTable; private SymbolTable symbolTable;
private SymbolTable fileTable; private SymbolTable fileTable;
private ReferenceCache referenceCache = new ReferenceCache(); private ReferenceCache referenceCache;
private static BinaryOperation[] binaryOperations = BinaryOperation.values(); private static BinaryOperation[] binaryOperations = BinaryOperation.values();
private static NumericOperandType[] numericOperandTypes = NumericOperandType.values(); private static NumericOperandType[] numericOperandTypes = NumericOperandType.values();
private static IntegerSubtype[] integerSubtypes = IntegerSubtype.values(); private static IntegerSubtype[] integerSubtypes = IntegerSubtype.values();
@ -94,7 +94,8 @@ public class ProgramIO {
private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.values(); private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.values();
private static ArrayElementType[] arrayElementTypes = ArrayElementType.values(); private static ArrayElementType[] arrayElementTypes = ArrayElementType.values();
public ProgramIO(SymbolTable symbolTable, SymbolTable fileTable) { public ProgramIO(ReferenceCache referenceCache, SymbolTable symbolTable, SymbolTable fileTable) {
this.referenceCache = referenceCache;
this.symbolTable = symbolTable; this.symbolTable = symbolTable;
this.fileTable = fileTable; this.fileTable = fileTable;
} }

View File

@ -51,7 +51,11 @@ public class DebugInformation {
Map<String, ClassMetadata> classMetadataByJsName; Map<String, ClassMetadata> classMetadataByJsName;
RecordArray methodEntrances; RecordArray methodEntrances;
MethodTree methodTree; MethodTree methodTree;
ReferenceCache referenceCache = new ReferenceCache(); ReferenceCache referenceCache;
public DebugInformation(ReferenceCache referenceCache) {
this.referenceCache = referenceCache;
}
public String[] getFilesNames() { public String[] getFilesNames() {
return fileNames.clone(); return fileNames.clone();
@ -410,7 +414,11 @@ public class DebugInformation {
} }
public static DebugInformation read(InputStream input) throws IOException { public static DebugInformation read(InputStream input) throws IOException {
DebugInformationReader reader = new DebugInformationReader(input); return read(input, new ReferenceCache());
}
public static DebugInformation read(InputStream input, ReferenceCache referenceCache) throws IOException {
DebugInformationReader reader = new DebugInformationReader(input, referenceCache);
return reader.read(); return reader.read();
} }

View File

@ -21,6 +21,7 @@ import org.teavm.common.RecordArray;
import org.teavm.common.RecordArrayBuilder; import org.teavm.common.RecordArrayBuilder;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ReferenceCache;
public class DebugInformationBuilder implements DebugInformationEmitter { public class DebugInformationBuilder implements DebugInformationEmitter {
private LocationProvider locationProvider; private LocationProvider locationProvider;
@ -46,6 +47,11 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
private List<ClassMetadata> classesMetadata = new ArrayList<>(); private List<ClassMetadata> classesMetadata = new ArrayList<>();
private List<RecordArrayBuilder> cfgs = new ArrayList<>(); private List<RecordArrayBuilder> cfgs = new ArrayList<>();
private int currentLine; private int currentLine;
private ReferenceCache referenceCache;
public DebugInformationBuilder(ReferenceCache referenceCache) {
this.referenceCache = referenceCache;
}
public LocationProvider getLocationProvider() { public LocationProvider getLocationProvider() {
return locationProvider; return locationProvider;
@ -263,7 +269,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
public DebugInformation getDebugInformation() { public DebugInformation getDebugInformation() {
if (debugInformation == null) { if (debugInformation == null) {
debugInformation = new DebugInformation(); debugInformation = new DebugInformation(referenceCache);
debugInformation.fileNames = files.getItems(); debugInformation.fileNames = files.getItems();
debugInformation.classNames = classes.getItems(); debugInformation.classNames = classes.getItems();

View File

@ -23,17 +23,20 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.teavm.common.RecordArray; import org.teavm.common.RecordArray;
import org.teavm.common.RecordArrayBuilder; import org.teavm.common.RecordArrayBuilder;
import org.teavm.model.ReferenceCache;
class DebugInformationReader { class DebugInformationReader {
private InputStream input; private InputStream input;
private int lastNumber; private int lastNumber;
private ReferenceCache referenceCache;
public DebugInformationReader(InputStream input) { DebugInformationReader(InputStream input, ReferenceCache referenceCache) {
this.input = input; this.input = input;
this.referenceCache = referenceCache;
} }
public DebugInformation read() throws IOException { public DebugInformation read() throws IOException {
DebugInformation debugInfo = new DebugInformation(); DebugInformation debugInfo = new DebugInformation(referenceCache);
debugInfo.fileNames = readStrings(); debugInfo.fileNames = readStrings();
debugInfo.classNames = readStrings(); debugInfo.classNames = readStrings();
debugInfo.fields = readStrings(); debugInfo.fields = readStrings();

View File

@ -113,11 +113,13 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
private ClassHierarchy classHierarchy; private ClassHierarchy classHierarchy;
IncrementalCache incrementalCache = new IncrementalCache(); IncrementalCache incrementalCache = new IncrementalCache();
boolean asyncSupported; boolean asyncSupported;
private ReferenceCache referenceCache;
DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
Diagnostics diagnostics) { Diagnostics diagnostics, ReferenceCache referenceCache) {
unprocessedClassSource = classSource; unprocessedClassSource = classSource;
this.diagnostics = diagnostics; this.diagnostics = diagnostics;
this.referenceCache = referenceCache;
this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache); this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache);
classHierarchy = new ClassHierarchy(this.classSource); classHierarchy = new ClassHierarchy(this.classSource);
this.classLoader = classLoader; this.classLoader = classLoader;
@ -231,7 +233,7 @@ public abstract class DependencyAnalyzer implements DependencyInfo {
ClassNode node = new ClassNode(); ClassNode node = new ClassNode();
org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(data); org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(data);
reader.accept(node, 0); reader.accept(node, 0);
submitClass(new Parser(new ReferenceCache()).parseClass(node)); submitClass(new Parser(referenceCache).parseClass(node));
return node.name; return node.name;
} }

View File

@ -18,8 +18,9 @@ package org.teavm.dependency;
import org.teavm.common.ServiceRepository; import org.teavm.common.ServiceRepository;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
import org.teavm.model.ReferenceCache;
public interface DependencyAnalyzerFactory { public interface DependencyAnalyzerFactory {
DependencyAnalyzer create(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, DependencyAnalyzer create(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
Diagnostics diagnostics); Diagnostics diagnostics, ReferenceCache referenceCache);
} }

View File

@ -31,6 +31,7 @@ import org.teavm.model.FieldReference;
import org.teavm.model.MethodReader; import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ProgramReader; import org.teavm.model.ProgramReader;
import org.teavm.model.ReferenceCache;
import org.teavm.model.TryCatchBlockReader; import org.teavm.model.TryCatchBlockReader;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
@ -41,8 +42,8 @@ public class FastDependencyAnalyzer extends DependencyAnalyzer {
private Map<String, DependencyNode> subtypeNodes = new HashMap<>(); private Map<String, DependencyNode> subtypeNodes = new HashMap<>();
public FastDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, public FastDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader,
ServiceRepository services, Diagnostics diagnostics) { ServiceRepository services, Diagnostics diagnostics, ReferenceCache referenceCache) {
super(classSource, classLoader, services, diagnostics); super(classSource, classLoader, services, diagnostics, referenceCache);
instancesNode = new DependencyNode(this, null); instancesNode = new DependencyNode(this, null);
classesNode = new DependencyNode(this, null); classesNode = new DependencyNode(this, null);

View File

@ -20,12 +20,13 @@ import org.teavm.diagnostics.Diagnostics;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
import org.teavm.model.FieldReference; import org.teavm.model.FieldReference;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.ReferenceCache;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
public class PreciseDependencyAnalyzer extends DependencyAnalyzer { public class PreciseDependencyAnalyzer extends DependencyAnalyzer {
public PreciseDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, public PreciseDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader,
ServiceRepository services, Diagnostics diagnostics) { ServiceRepository services, Diagnostics diagnostics, ReferenceCache referenceCache) {
super(classSource, classLoader, services, diagnostics); super(classSource, classLoader, services, diagnostics, referenceCache);
} }
@Override @Override

View File

@ -27,16 +27,15 @@ public class ClasspathClassHolderSource implements ClassHolderSource, ClassDateP
private MapperClassHolderSource innerClassSource; private MapperClassHolderSource innerClassSource;
private ClasspathResourceMapper classPathMapper; private ClasspathResourceMapper classPathMapper;
public ClasspathClassHolderSource(ClassLoader classLoader) { public ClasspathClassHolderSource(ClassLoader classLoader, ReferenceCache referenceCache) {
ReferenceCache referenceCache = new ReferenceCache();
ClasspathResourceReader reader = new ClasspathResourceReader(classLoader); ClasspathResourceReader reader = new ClasspathResourceReader(classLoader);
ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache); ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache);
classPathMapper = new ClasspathResourceMapper(classLoader, referenceCache, rawMapper); classPathMapper = new ClasspathResourceMapper(classLoader, referenceCache, rawMapper);
innerClassSource = new MapperClassHolderSource(classPathMapper); innerClassSource = new MapperClassHolderSource(classPathMapper);
} }
public ClasspathClassHolderSource() { public ClasspathClassHolderSource(ReferenceCache referenceCache) {
this(ClasspathClassHolderSource.class.getClassLoader()); this(ClasspathClassHolderSource.class.getClassLoader(), referenceCache);
} }
@Override @Override

View File

@ -29,16 +29,15 @@ public class DirectoryClasspathClassHolderSource implements ClassHolderSource {
private MapperClassHolderSource innerClassSource; private MapperClassHolderSource innerClassSource;
private ClasspathResourceMapper classPathMapper; private ClasspathResourceMapper classPathMapper;
public DirectoryClasspathClassHolderSource(File baseDir, Properties properties) { public DirectoryClasspathClassHolderSource(File baseDir, Properties properties, ReferenceCache referenceCache) {
ReferenceCache referenceCache = new ReferenceCache();
DirectoryResourceReader reader = new DirectoryResourceReader(baseDir); DirectoryResourceReader reader = new DirectoryResourceReader(baseDir);
ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache); ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache);
classPathMapper = new ClasspathResourceMapper(properties, referenceCache, rawMapper); classPathMapper = new ClasspathResourceMapper(properties, referenceCache, rawMapper);
innerClassSource = new MapperClassHolderSource(classPathMapper); innerClassSource = new MapperClassHolderSource(classPathMapper);
} }
public DirectoryClasspathClassHolderSource(File baseDir) { public DirectoryClasspathClassHolderSource(File baseDir, ReferenceCache referenceCache) {
this(baseDir, new Properties()); this(baseDir, new Properties(), referenceCache);
} }
@Override @Override

View File

@ -158,7 +158,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
classSource = builder.classSource; classSource = builder.classSource;
classLoader = builder.classLoader; classLoader = builder.classLoader;
dependencyAnalyzer = builder.dependencyAnalyzerFactory.create(this.classSource, classLoader, dependencyAnalyzer = builder.dependencyAnalyzerFactory.create(this.classSource, classLoader,
this, diagnostics); this, diagnostics, builder.referenceCache);
progressListener = new TeaVMProgressListener() { progressListener = new TeaVMProgressListener() {
@Override public TeaVMProgressFeedback progressReached(int progress) { @Override public TeaVMProgressFeedback progressReached(int progress) {
return TeaVMProgressFeedback.CONTINUE; return TeaVMProgressFeedback.CONTINUE;

View File

@ -19,18 +19,20 @@ import org.teavm.dependency.DependencyAnalyzerFactory;
import org.teavm.dependency.PreciseDependencyAnalyzer; import org.teavm.dependency.PreciseDependencyAnalyzer;
import org.teavm.interop.PlatformMarker; import org.teavm.interop.PlatformMarker;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
import org.teavm.model.ReferenceCache;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
public class TeaVMBuilder { public class TeaVMBuilder {
TeaVMTarget target; TeaVMTarget target;
ClassReaderSource classSource; ClassReaderSource classSource;
ClassLoader classLoader; ClassLoader classLoader;
ReferenceCache referenceCache = new ReferenceCache();
DependencyAnalyzerFactory dependencyAnalyzerFactory = PreciseDependencyAnalyzer::new; DependencyAnalyzerFactory dependencyAnalyzerFactory = PreciseDependencyAnalyzer::new;
public TeaVMBuilder(TeaVMTarget target) { public TeaVMBuilder(TeaVMTarget target) {
this.target = target; this.target = target;
classLoader = TeaVMBuilder.class.getClassLoader(); classLoader = TeaVMBuilder.class.getClassLoader();
classSource = !isBootstrap() ? new ClasspathClassHolderSource(classLoader) : name -> null; classSource = !isBootstrap() ? new ClasspathClassHolderSource(classLoader, referenceCache) : name -> null;
} }
public ClassReaderSource getClassSource() { public ClassReaderSource getClassSource() {
@ -60,6 +62,11 @@ public class TeaVMBuilder {
return this; return this;
} }
public TeaVMBuilder setReferenceCache(ReferenceCache referenceCache) {
this.referenceCache = referenceCache;
return this;
}
public TeaVM build() { public TeaVM build() {
return new TeaVM(this); return new TeaVM(this);
} }

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlock;
import org.teavm.model.Instruction; import org.teavm.model.Instruction;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ReferenceCache;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.model.instructions.*; import org.teavm.model.instructions.*;
@ -157,7 +158,7 @@ public class ProgramIOTest {
private Program inputOutput(Program program) { private Program inputOutput(Program program) {
InMemorySymbolTable symbolTable = new InMemorySymbolTable(); InMemorySymbolTable symbolTable = new InMemorySymbolTable();
InMemorySymbolTable fileTable = new InMemorySymbolTable(); InMemorySymbolTable fileTable = new InMemorySymbolTable();
ProgramIO programIO = new ProgramIO(symbolTable, fileTable); ProgramIO programIO = new ProgramIO(new ReferenceCache(), symbolTable, fileTable);
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
programIO.write(program, output); programIO.write(program, output);
try (ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray())) { try (ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray())) {

View File

@ -39,6 +39,7 @@ import org.teavm.model.Instruction;
import org.teavm.model.MethodHolder; import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ReferenceCache;
import org.teavm.model.TextLocation; import org.teavm.model.TextLocation;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.model.analysis.ClassInference; import org.teavm.model.analysis.ClassInference;
@ -63,7 +64,8 @@ public class DependencyTest {
@BeforeClass @BeforeClass
public static void prepare() { public static void prepare() {
classSource = new ClasspathClassHolderSource(DependencyTest.class.getClassLoader()); classSource = new ClasspathClassHolderSource(DependencyTest.class.getClassLoader(),
new ReferenceCache());
} }
@AfterClass @AfterClass

View File

@ -58,6 +58,7 @@ import org.teavm.model.ClassHolderSource;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.Program; import org.teavm.model.Program;
import org.teavm.model.ReferenceCache;
import org.teavm.model.util.ModelUtils; import org.teavm.model.util.ModelUtils;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
import org.teavm.tooling.TeaVMProblemRenderer; import org.teavm.tooling.TeaVMProblemRenderer;
@ -71,7 +72,7 @@ public class IncrementalTest {
private static final String NEW_FILE = "classes-new.js"; private static final String NEW_FILE = "classes-new.js";
private static final String REFRESHED_FILE = "classes-refreshed.js"; private static final String REFRESHED_FILE = "classes-refreshed.js";
private static ClassHolderSource oldClassSource = new ClasspathClassHolderSource( private static ClassHolderSource oldClassSource = new ClasspathClassHolderSource(
IncrementalTest.class.getClassLoader()); IncrementalTest.class.getClassLoader(), new ReferenceCache());
private static Context rhinoContext; private static Context rhinoContext;
private static ScriptableObject rhinoRootScope; private static ScriptableObject rhinoRootScope;
private String[] updatedMethods; private String[] updatedMethods;
@ -238,7 +239,7 @@ public class IncrementalTest {
boolean capturing; boolean capturing;
CapturingMethodNodeCache() { CapturingMethodNodeCache() {
super(new InMemorySymbolTable(), new InMemorySymbolTable()); super(new ReferenceCache(), new InMemorySymbolTable(), new InMemorySymbolTable());
} }
@Override @Override
@ -263,7 +264,7 @@ public class IncrementalTest {
boolean capturing; boolean capturing;
CapturingProgramCache() { CapturingProgramCache() {
super(new InMemorySymbolTable(), new InMemorySymbolTable()); super(new ReferenceCache(), new InMemorySymbolTable(), new InMemorySymbolTable());
} }
@Override @Override

View File

@ -53,6 +53,7 @@ import org.teavm.model.ClassHolderSource;
import org.teavm.model.ClassHolderTransformer; import org.teavm.model.ClassHolderTransformer;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.PreOptimizingClassHolderSource; import org.teavm.model.PreOptimizingClassHolderSource;
import org.teavm.model.ReferenceCache;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
import org.teavm.tooling.sources.SourceFileProvider; import org.teavm.tooling.sources.SourceFileProvider;
import org.teavm.tooling.sources.SourceFilesCopier; import org.teavm.tooling.sources.SourceFilesCopier;
@ -100,6 +101,7 @@ public class TeaVMTool {
private CTarget cTarget; private CTarget cTarget;
private Set<File> generatedFiles = new HashSet<>(); private Set<File> generatedFiles = new HashSet<>();
private int minHeapSize = 32 * (1 << 20); private int minHeapSize = 32 * (1 << 20);
private ReferenceCache referenceCache;
public File getTargetDirectory() { public File getTargetDirectory() {
return targetDirectory; return targetDirectory;
@ -299,7 +301,7 @@ public class TeaVMTool {
javaScriptTarget.setTopLevelNameLimit(maxTopLevelNames); javaScriptTarget.setTopLevelNameLimit(maxTopLevelNames);
debugEmitter = debugInformationGenerated || sourceMapsFileGenerated debugEmitter = debugInformationGenerated || sourceMapsFileGenerated
? new DebugInformationBuilder() : null; ? new DebugInformationBuilder(referenceCache) : null;
javaScriptTarget.setDebugEmitter(debugEmitter); javaScriptTarget.setDebugEmitter(debugEmitter);
return javaScriptTarget; return javaScriptTarget;
@ -327,17 +329,20 @@ public class TeaVMTool {
log.info("Running TeaVM"); log.info("Running TeaVM");
TeaVMBuilder vmBuilder = new TeaVMBuilder(prepareTarget()); TeaVMBuilder vmBuilder = new TeaVMBuilder(prepareTarget());
CacheStatus cacheStatus; CacheStatus cacheStatus;
referenceCache = new ReferenceCache();
vmBuilder.setReferenceCache(referenceCache);
if (incremental) { if (incremental) {
cacheDirectory.mkdirs(); cacheDirectory.mkdirs();
symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols")); symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols"));
fileTable = new FileSymbolTable(new File(cacheDirectory, "files")); fileTable = new FileSymbolTable(new File(cacheDirectory, "files"));
ClasspathClassHolderSource innerClassSource = new ClasspathClassHolderSource(classLoader); ClasspathClassHolderSource innerClassSource = new ClasspathClassHolderSource(classLoader,
referenceCache);
ClassHolderSource classSource = new PreOptimizingClassHolderSource(innerClassSource); ClassHolderSource classSource = new PreOptimizingClassHolderSource(innerClassSource);
cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, symbolTable, fileTable, cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, referenceCache, symbolTable,
classSource, innerClassSource); fileTable, classSource, innerClassSource);
programCache = new DiskProgramCache(cacheDirectory, symbolTable, fileTable); programCache = new DiskProgramCache(cacheDirectory, referenceCache, symbolTable, fileTable);
if (incremental && targetType == TeaVMTargetType.JAVASCRIPT) { if (incremental && targetType == TeaVMTargetType.JAVASCRIPT) {
astCache = new DiskMethodNodeCache(cacheDirectory, symbolTable, fileTable); astCache = new DiskMethodNodeCache(cacheDirectory, referenceCache, symbolTable, fileTable);
javaScriptTarget.setAstCache(astCache); javaScriptTarget.setAstCache(astCache);
} }
try { try {
@ -350,7 +355,7 @@ public class TeaVMTool {
cacheStatus = cachedClassSource; cacheStatus = cachedClassSource;
} else { } else {
vmBuilder.setClassLoader(classLoader).setClassSource(new PreOptimizingClassHolderSource( vmBuilder.setClassLoader(classLoader).setClassSource(new PreOptimizingClassHolderSource(
new ClasspathClassHolderSource(classLoader))); new ClasspathClassHolderSource(classLoader, referenceCache)));
cacheStatus = AlwaysStaleCacheStatus.INSTANCE; cacheStatus = AlwaysStaleCacheStatus.INSTANCE;
} }

View File

@ -76,6 +76,7 @@ import org.teavm.debugging.information.DebugInformationBuilder;
import org.teavm.dependency.FastDependencyAnalyzer; import org.teavm.dependency.FastDependencyAnalyzer;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.PreOptimizingClassHolderSource; import org.teavm.model.PreOptimizingClassHolderSource;
import org.teavm.model.ReferenceCache;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMProblemRenderer; import org.teavm.tooling.TeaVMProblemRenderer;
@ -139,6 +140,7 @@ public class CodeServlet extends HttpServlet {
private WebSocketClient wsClient = new WebSocketClient(); private WebSocketClient wsClient = new WebSocketClient();
private InMemorySymbolTable symbolTable = new InMemorySymbolTable(); private InMemorySymbolTable symbolTable = new InMemorySymbolTable();
private InMemorySymbolTable fileSymbolTable = new InMemorySymbolTable(); private InMemorySymbolTable fileSymbolTable = new InMemorySymbolTable();
private ReferenceCache referenceCache = new ReferenceCache();
public CodeServlet(String mainClass, String[] classPath) { public CodeServlet(String mainClass, String[] classPath) {
this.mainClass = mainClass; this.mainClass = mainClass;
@ -707,8 +709,8 @@ public class CodeServlet extends HttpServlet {
watcher = new FileSystemWatcher(classPath); watcher = new FileSystemWatcher(classPath);
classSource = new MemoryCachedClassReaderSource(); classSource = new MemoryCachedClassReaderSource();
astCache = new InMemoryMethodNodeCache(symbolTable, fileSymbolTable); astCache = new InMemoryMethodNodeCache(referenceCache, symbolTable, fileSymbolTable);
programCache = new InMemoryProgramCache(symbolTable, fileSymbolTable); programCache = new InMemoryProgramCache(referenceCache, symbolTable, fileSymbolTable);
} }
private void shutdownBuilder() { private void shutdownBuilder() {
@ -733,15 +735,16 @@ public class CodeServlet extends HttpServlet {
fireBuildStarted(); fireBuildStarted();
reportProgress(0); reportProgress(0);
DebugInformationBuilder debugInformationBuilder = new DebugInformationBuilder(); DebugInformationBuilder debugInformationBuilder = new DebugInformationBuilder(referenceCache);
ClassLoader classLoader = initClassLoader(); ClassLoader classLoader = initClassLoader();
classSource.setUnderlyingSource(new PreOptimizingClassHolderSource( classSource.setUnderlyingSource(new PreOptimizingClassHolderSource(
new ClasspathClassHolderSource(classLoader))); new ClasspathClassHolderSource(classLoader, referenceCache)));
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
JavaScriptTarget jsTarget = new JavaScriptTarget(); JavaScriptTarget jsTarget = new JavaScriptTarget();
TeaVM vm = new TeaVMBuilder(jsTarget) TeaVM vm = new TeaVMBuilder(jsTarget)
.setReferenceCache(referenceCache)
.setClassLoader(classLoader) .setClassLoader(classLoader)
.setClassSource(classSource) .setClassSource(classSource)
.setDependencyAnalyzerFactory(FastDependencyAnalyzer::new) .setDependencyAnalyzerFactory(FastDependencyAnalyzer::new)

View File

@ -76,6 +76,7 @@ import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodHolder; import org.teavm.model.MethodHolder;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.PreOptimizingClassHolderSource; import org.teavm.model.PreOptimizingClassHolderSource;
import org.teavm.model.ReferenceCache;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
import org.teavm.tooling.TeaVMProblemRenderer; import org.teavm.tooling.TeaVMProblemRenderer;
@ -116,6 +117,7 @@ public class TeaVMTestRunner extends Runner implements Filterable {
private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
private CountDownLatch latch; private CountDownLatch latch;
private List<Method> filteredChildren; private List<Method> filteredChildren;
private ReferenceCache referenceCache = new ReferenceCache();
static class RunnerKindInfo { static class RunnerKindInfo {
volatile TestRunner runner; volatile TestRunner runner;
@ -559,7 +561,7 @@ public class TeaVMTestRunner extends Runner implements Filterable {
private CompileResult compileToJs(Method method, TeaVMTestConfiguration<JavaScriptTarget> configuration, private CompileResult compileToJs(Method method, TeaVMTestConfiguration<JavaScriptTarget> configuration,
File path) { File path) {
boolean decodeStack = Boolean.parseBoolean(System.getProperty(JS_DECODE_STACK, "true")); boolean decodeStack = Boolean.parseBoolean(System.getProperty(JS_DECODE_STACK, "true"));
DebugInformationBuilder debugEmitter = new DebugInformationBuilder(); DebugInformationBuilder debugEmitter = new DebugInformationBuilder(new ReferenceCache());
Supplier<JavaScriptTarget> targetSupplier = () -> { Supplier<JavaScriptTarget> targetSupplier = () -> {
JavaScriptTarget target = new JavaScriptTarget(); JavaScriptTarget target = new JavaScriptTarget();
if (decodeStack) { if (decodeStack) {
@ -639,6 +641,7 @@ public class TeaVMTestRunner extends Runner implements Filterable {
TeaVM vm = new TeaVMBuilder(target) TeaVM vm = new TeaVMBuilder(target)
.setClassLoader(classLoader) .setClassLoader(classLoader)
.setClassSource(classSource) .setClassSource(classSource)
.setReferenceCache(referenceCache)
.setDependencyAnalyzerFactory(dependencyAnalyzerFactory) .setDependencyAnalyzerFactory(dependencyAnalyzerFactory)
.build(); .build();
@ -751,9 +754,9 @@ public class TeaVMTestRunner extends Runner implements Filterable {
} }
} }
private static ClassHolderSource getClassSource(ClassLoader classLoader) { private ClassHolderSource getClassSource(ClassLoader classLoader) {
return classSources.computeIfAbsent(classLoader, cl -> new PreOptimizingClassHolderSource( return classSources.computeIfAbsent(classLoader, cl -> new PreOptimizingClassHolderSource(
new ClasspathClassHolderSource(classLoader))); new ClasspathClassHolderSource(classLoader, referenceCache)));
} }
@Override @Override