From 2a1aca98da7bf035af6d293ba83a76e12a164afc Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 5 Mar 2019 19:32:50 +0300 Subject: [PATCH] Use shared ReferenceCache between different stages of compilation --- .../impl/report/JCLComparisonBuilder.java | 3 ++- core/src/main/java/org/teavm/cache/AstIO.java | 5 +++-- .../cache/DiskCachedClassHolderSource.java | 7 ++++--- .../org/teavm/cache/DiskMethodNodeCache.java | 6 ++++-- .../org/teavm/cache/DiskProgramCache.java | 6 ++++-- .../teavm/cache/InMemoryMethodNodeCache.java | 6 ++++-- .../org/teavm/cache/InMemoryProgramCache.java | 6 ++++-- .../main/java/org/teavm/cache/ProgramIO.java | 5 +++-- .../information/DebugInformation.java | 12 ++++++++++-- .../information/DebugInformationBuilder.java | 8 +++++++- .../information/DebugInformationReader.java | 7 +++++-- .../teavm/dependency/DependencyAnalyzer.java | 6 ++++-- .../dependency/DependencyAnalyzerFactory.java | 3 ++- .../dependency/FastDependencyAnalyzer.java | 5 +++-- .../dependency/PreciseDependencyAnalyzer.java | 5 +++-- .../parsing/ClasspathClassHolderSource.java | 7 +++---- .../DirectoryClasspathClassHolderSource.java | 7 +++---- core/src/main/java/org/teavm/vm/TeaVM.java | 2 +- .../main/java/org/teavm/vm/TeaVMBuilder.java | 9 ++++++++- .../java/org/teavm/cache/ProgramIOTest.java | 3 ++- .../org/teavm/dependency/DependencyTest.java | 4 +++- .../teavm/incremental/IncrementalTest.java | 7 ++++--- .../java/org/teavm/tooling/TeaVMTool.java | 19 ++++++++++++------- .../java/org/teavm/devserver/CodeServlet.java | 11 +++++++---- .../java/org/teavm/junit/TeaVMTestRunner.java | 9 ++++++--- 25 files changed, 111 insertions(+), 57 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/impl/report/JCLComparisonBuilder.java b/classlib/src/main/java/org/teavm/classlib/impl/report/JCLComparisonBuilder.java index 27d1aaf46..f22ebbf26 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/report/JCLComparisonBuilder.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/report/JCLComparisonBuilder.java @@ -24,6 +24,7 @@ import java.util.jar.JarInputStream; import org.apache.commons.io.IOUtils; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Type; +import org.teavm.model.ReferenceCache; import org.teavm.parsing.ClasspathClassHolderSource; public class JCLComparisonBuilder { @@ -119,7 +120,7 @@ public class JCLComparisonBuilder { if (!path.startsWith(JAR_PREFIX) || !path.endsWith(JAR_SUFFIX)) { 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()); File outDir = new File(outputDirectory).getParentFile(); if (!outDir.exists()) { diff --git a/core/src/main/java/org/teavm/cache/AstIO.java b/core/src/main/java/org/teavm/cache/AstIO.java index 214aeeda5..bd14165fe 100644 --- a/core/src/main/java/org/teavm/cache/AstIO.java +++ b/core/src/main/java/org/teavm/cache/AstIO.java @@ -83,9 +83,10 @@ public class AstIO { private final SymbolTable symbolTable; private final SymbolTable fileTable; private final Map 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.fileTable = fileTable; } diff --git a/core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java b/core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java index 83d20f5ef..dd268fafd 100644 --- a/core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java +++ b/core/src/main/java/org/teavm/cache/DiskCachedClassHolderSource.java @@ -48,6 +48,7 @@ import org.teavm.model.FieldReference; import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodHolder; import org.teavm.model.MethodReference; +import org.teavm.model.ReferenceCache; import org.teavm.model.ValueType; import org.teavm.parsing.ClassDateProvider; @@ -62,13 +63,13 @@ public class DiskCachedClassHolderSource implements ClassHolderSource, CacheStat private Set newClasses = new HashSet<>(); private ProgramIO programIO; - public DiskCachedClassHolderSource(File directory, SymbolTable symbolTable, SymbolTable fileTable, - ClassHolderSource innerSource, ClassDateProvider classDateProvider) { + public DiskCachedClassHolderSource(File directory, ReferenceCache referenceCache, SymbolTable symbolTable, + SymbolTable fileTable, ClassHolderSource innerSource, ClassDateProvider classDateProvider) { this.directory = directory; this.symbolTable = symbolTable; this.innerSource = innerSource; this.classDateProvider = classDateProvider; - programIO = new ProgramIO(symbolTable, fileTable); + programIO = new ProgramIO(referenceCache, symbolTable, fileTable); } @Override diff --git a/core/src/main/java/org/teavm/cache/DiskMethodNodeCache.java b/core/src/main/java/org/teavm/cache/DiskMethodNodeCache.java index 37a21e910..56af8c319 100644 --- a/core/src/main/java/org/teavm/cache/DiskMethodNodeCache.java +++ b/core/src/main/java/org/teavm/cache/DiskMethodNodeCache.java @@ -31,6 +31,7 @@ import org.teavm.ast.AsyncMethodNode; import org.teavm.ast.ControlFlowEntry; import org.teavm.ast.RegularMethodNode; import org.teavm.model.MethodReference; +import org.teavm.model.ReferenceCache; public class DiskMethodNodeCache implements MethodNodeCache { private final File directory; @@ -40,9 +41,10 @@ public class DiskMethodNodeCache implements MethodNodeCache { private final Set newMethods = new HashSet<>(); private final Set newAsyncMethods = new HashSet<>(); - public DiskMethodNodeCache(File directory, SymbolTable symbolTable, SymbolTable fileTable) { + public DiskMethodNodeCache(File directory, ReferenceCache referenceCache, SymbolTable symbolTable, + SymbolTable fileTable) { this.directory = directory; - astIO = new AstIO(symbolTable, fileTable); + astIO = new AstIO(referenceCache, symbolTable, fileTable); } @Override diff --git a/core/src/main/java/org/teavm/cache/DiskProgramCache.java b/core/src/main/java/org/teavm/cache/DiskProgramCache.java index 4fd70e52c..6123b3af7 100644 --- a/core/src/main/java/org/teavm/cache/DiskProgramCache.java +++ b/core/src/main/java/org/teavm/cache/DiskProgramCache.java @@ -37,6 +37,7 @@ import org.teavm.model.ClassReaderSource; import org.teavm.model.MethodReference; import org.teavm.model.Program; import org.teavm.model.ProgramCache; +import org.teavm.model.ReferenceCache; public class DiskProgramCache implements ProgramCache { private File directory; @@ -44,9 +45,10 @@ public class DiskProgramCache implements ProgramCache { private Map cache = new HashMap<>(); private Set newMethods = new HashSet<>(); - public DiskProgramCache(File directory, SymbolTable symbolTable, SymbolTable fileTable) { + public DiskProgramCache(File directory, ReferenceCache referenceCache, SymbolTable symbolTable, + SymbolTable fileTable) { this.directory = directory; - programIO = new ProgramIO(symbolTable, fileTable); + programIO = new ProgramIO(referenceCache, symbolTable, fileTable); } @Override diff --git a/core/src/main/java/org/teavm/cache/InMemoryMethodNodeCache.java b/core/src/main/java/org/teavm/cache/InMemoryMethodNodeCache.java index ef4b3b754..55983acd3 100644 --- a/core/src/main/java/org/teavm/cache/InMemoryMethodNodeCache.java +++ b/core/src/main/java/org/teavm/cache/InMemoryMethodNodeCache.java @@ -26,6 +26,7 @@ import org.teavm.ast.AsyncMethodNode; import org.teavm.ast.ControlFlowEntry; import org.teavm.ast.RegularMethodNode; import org.teavm.model.MethodReference; +import org.teavm.model.ReferenceCache; public class InMemoryMethodNodeCache implements MethodNodeCache { private Map cache = new HashMap<>(); @@ -34,8 +35,9 @@ public class InMemoryMethodNodeCache implements MethodNodeCache { private Map newAsyncItems = new HashMap<>(); private AstIO io; - public InMemoryMethodNodeCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) { - io = new AstIO(symbolTable, fileSymbolTable); + public InMemoryMethodNodeCache(ReferenceCache referenceCache, InMemorySymbolTable symbolTable, + InMemorySymbolTable fileSymbolTable) { + io = new AstIO(referenceCache, symbolTable, fileSymbolTable); } @Override diff --git a/core/src/main/java/org/teavm/cache/InMemoryProgramCache.java b/core/src/main/java/org/teavm/cache/InMemoryProgramCache.java index 4bbb45ed5..9107327ee 100644 --- a/core/src/main/java/org/teavm/cache/InMemoryProgramCache.java +++ b/core/src/main/java/org/teavm/cache/InMemoryProgramCache.java @@ -25,14 +25,16 @@ import java.util.function.Supplier; import org.teavm.model.MethodReference; import org.teavm.model.Program; import org.teavm.model.ProgramCache; +import org.teavm.model.ReferenceCache; public class InMemoryProgramCache implements ProgramCache { private Map cache = new HashMap<>(); private Map newItems = new HashMap<>(); private ProgramIO io; - public InMemoryProgramCache(InMemorySymbolTable symbolTable, InMemorySymbolTable fileSymbolTable) { - io = new ProgramIO(symbolTable, fileSymbolTable); + public InMemoryProgramCache(ReferenceCache referenceCache, InMemorySymbolTable symbolTable, + InMemorySymbolTable fileSymbolTable) { + io = new ProgramIO(referenceCache, symbolTable, fileSymbolTable); } @Override diff --git a/core/src/main/java/org/teavm/cache/ProgramIO.java b/core/src/main/java/org/teavm/cache/ProgramIO.java index 31dd44abd..f656c129e 100644 --- a/core/src/main/java/org/teavm/cache/ProgramIO.java +++ b/core/src/main/java/org/teavm/cache/ProgramIO.java @@ -85,7 +85,7 @@ import org.teavm.model.instructions.UnwrapArrayInstruction; public class ProgramIO { private SymbolTable symbolTable; private SymbolTable fileTable; - private ReferenceCache referenceCache = new ReferenceCache(); + private ReferenceCache referenceCache; private static BinaryOperation[] binaryOperations = BinaryOperation.values(); private static NumericOperandType[] numericOperandTypes = NumericOperandType.values(); private static IntegerSubtype[] integerSubtypes = IntegerSubtype.values(); @@ -94,7 +94,8 @@ public class ProgramIO { private static BinaryBranchingCondition[] binaryBranchingConditions = BinaryBranchingCondition.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.fileTable = fileTable; } diff --git a/core/src/main/java/org/teavm/debugging/information/DebugInformation.java b/core/src/main/java/org/teavm/debugging/information/DebugInformation.java index 268fe8ab1..557dbb7ca 100644 --- a/core/src/main/java/org/teavm/debugging/information/DebugInformation.java +++ b/core/src/main/java/org/teavm/debugging/information/DebugInformation.java @@ -51,7 +51,11 @@ public class DebugInformation { Map classMetadataByJsName; RecordArray methodEntrances; MethodTree methodTree; - ReferenceCache referenceCache = new ReferenceCache(); + ReferenceCache referenceCache; + + public DebugInformation(ReferenceCache referenceCache) { + this.referenceCache = referenceCache; + } public String[] getFilesNames() { return fileNames.clone(); @@ -410,7 +414,11 @@ public class DebugInformation { } 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(); } diff --git a/core/src/main/java/org/teavm/debugging/information/DebugInformationBuilder.java b/core/src/main/java/org/teavm/debugging/information/DebugInformationBuilder.java index 61d7bbf4c..ffcd071a7 100644 --- a/core/src/main/java/org/teavm/debugging/information/DebugInformationBuilder.java +++ b/core/src/main/java/org/teavm/debugging/information/DebugInformationBuilder.java @@ -21,6 +21,7 @@ import org.teavm.common.RecordArray; import org.teavm.common.RecordArrayBuilder; import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodReference; +import org.teavm.model.ReferenceCache; public class DebugInformationBuilder implements DebugInformationEmitter { private LocationProvider locationProvider; @@ -46,6 +47,11 @@ public class DebugInformationBuilder implements DebugInformationEmitter { private List classesMetadata = new ArrayList<>(); private List cfgs = new ArrayList<>(); private int currentLine; + private ReferenceCache referenceCache; + + public DebugInformationBuilder(ReferenceCache referenceCache) { + this.referenceCache = referenceCache; + } public LocationProvider getLocationProvider() { return locationProvider; @@ -263,7 +269,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter { public DebugInformation getDebugInformation() { if (debugInformation == null) { - debugInformation = new DebugInformation(); + debugInformation = new DebugInformation(referenceCache); debugInformation.fileNames = files.getItems(); debugInformation.classNames = classes.getItems(); diff --git a/core/src/main/java/org/teavm/debugging/information/DebugInformationReader.java b/core/src/main/java/org/teavm/debugging/information/DebugInformationReader.java index d4010111a..e33c5fac7 100644 --- a/core/src/main/java/org/teavm/debugging/information/DebugInformationReader.java +++ b/core/src/main/java/org/teavm/debugging/information/DebugInformationReader.java @@ -23,17 +23,20 @@ import java.util.ArrayList; import java.util.List; import org.teavm.common.RecordArray; import org.teavm.common.RecordArrayBuilder; +import org.teavm.model.ReferenceCache; class DebugInformationReader { private InputStream input; private int lastNumber; + private ReferenceCache referenceCache; - public DebugInformationReader(InputStream input) { + DebugInformationReader(InputStream input, ReferenceCache referenceCache) { this.input = input; + this.referenceCache = referenceCache; } public DebugInformation read() throws IOException { - DebugInformation debugInfo = new DebugInformation(); + DebugInformation debugInfo = new DebugInformation(referenceCache); debugInfo.fileNames = readStrings(); debugInfo.classNames = readStrings(); debugInfo.fields = readStrings(); diff --git a/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java b/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java index dcb4415ef..64e3d601f 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java +++ b/core/src/main/java/org/teavm/dependency/DependencyAnalyzer.java @@ -113,11 +113,13 @@ public abstract class DependencyAnalyzer implements DependencyInfo { private ClassHierarchy classHierarchy; IncrementalCache incrementalCache = new IncrementalCache(); boolean asyncSupported; + private ReferenceCache referenceCache; DependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, - Diagnostics diagnostics) { + Diagnostics diagnostics, ReferenceCache referenceCache) { unprocessedClassSource = classSource; this.diagnostics = diagnostics; + this.referenceCache = referenceCache; this.classSource = new DependencyClassSource(classSource, diagnostics, incrementalCache); classHierarchy = new ClassHierarchy(this.classSource); this.classLoader = classLoader; @@ -231,7 +233,7 @@ public abstract class DependencyAnalyzer implements DependencyInfo { ClassNode node = new ClassNode(); org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(data); reader.accept(node, 0); - submitClass(new Parser(new ReferenceCache()).parseClass(node)); + submitClass(new Parser(referenceCache).parseClass(node)); return node.name; } diff --git a/core/src/main/java/org/teavm/dependency/DependencyAnalyzerFactory.java b/core/src/main/java/org/teavm/dependency/DependencyAnalyzerFactory.java index 1136724bf..d129790b8 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyAnalyzerFactory.java +++ b/core/src/main/java/org/teavm/dependency/DependencyAnalyzerFactory.java @@ -18,8 +18,9 @@ package org.teavm.dependency; import org.teavm.common.ServiceRepository; import org.teavm.diagnostics.Diagnostics; import org.teavm.model.ClassReaderSource; +import org.teavm.model.ReferenceCache; public interface DependencyAnalyzerFactory { DependencyAnalyzer create(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services, - Diagnostics diagnostics); + Diagnostics diagnostics, ReferenceCache referenceCache); } diff --git a/core/src/main/java/org/teavm/dependency/FastDependencyAnalyzer.java b/core/src/main/java/org/teavm/dependency/FastDependencyAnalyzer.java index 33b77e0dd..a914bb1a9 100644 --- a/core/src/main/java/org/teavm/dependency/FastDependencyAnalyzer.java +++ b/core/src/main/java/org/teavm/dependency/FastDependencyAnalyzer.java @@ -31,6 +31,7 @@ import org.teavm.model.FieldReference; import org.teavm.model.MethodReader; import org.teavm.model.MethodReference; import org.teavm.model.ProgramReader; +import org.teavm.model.ReferenceCache; import org.teavm.model.TryCatchBlockReader; import org.teavm.model.ValueType; @@ -41,8 +42,8 @@ public class FastDependencyAnalyzer extends DependencyAnalyzer { private Map subtypeNodes = new HashMap<>(); public FastDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, - ServiceRepository services, Diagnostics diagnostics) { - super(classSource, classLoader, services, diagnostics); + ServiceRepository services, Diagnostics diagnostics, ReferenceCache referenceCache) { + super(classSource, classLoader, services, diagnostics, referenceCache); instancesNode = new DependencyNode(this, null); classesNode = new DependencyNode(this, null); diff --git a/core/src/main/java/org/teavm/dependency/PreciseDependencyAnalyzer.java b/core/src/main/java/org/teavm/dependency/PreciseDependencyAnalyzer.java index c2f92b81d..ee72807a3 100644 --- a/core/src/main/java/org/teavm/dependency/PreciseDependencyAnalyzer.java +++ b/core/src/main/java/org/teavm/dependency/PreciseDependencyAnalyzer.java @@ -20,12 +20,13 @@ import org.teavm.diagnostics.Diagnostics; import org.teavm.model.ClassReaderSource; import org.teavm.model.FieldReference; import org.teavm.model.MethodReference; +import org.teavm.model.ReferenceCache; import org.teavm.model.ValueType; public class PreciseDependencyAnalyzer extends DependencyAnalyzer { public PreciseDependencyAnalyzer(ClassReaderSource classSource, ClassLoader classLoader, - ServiceRepository services, Diagnostics diagnostics) { - super(classSource, classLoader, services, diagnostics); + ServiceRepository services, Diagnostics diagnostics, ReferenceCache referenceCache) { + super(classSource, classLoader, services, diagnostics, referenceCache); } @Override diff --git a/core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java b/core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java index 0b3cd90c6..8b0f28f4f 100644 --- a/core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java +++ b/core/src/main/java/org/teavm/parsing/ClasspathClassHolderSource.java @@ -27,16 +27,15 @@ public class ClasspathClassHolderSource implements ClassHolderSource, ClassDateP private MapperClassHolderSource innerClassSource; private ClasspathResourceMapper classPathMapper; - public ClasspathClassHolderSource(ClassLoader classLoader) { - ReferenceCache referenceCache = new ReferenceCache(); + public ClasspathClassHolderSource(ClassLoader classLoader, ReferenceCache referenceCache) { ClasspathResourceReader reader = new ClasspathResourceReader(classLoader); ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache); classPathMapper = new ClasspathResourceMapper(classLoader, referenceCache, rawMapper); innerClassSource = new MapperClassHolderSource(classPathMapper); } - public ClasspathClassHolderSource() { - this(ClasspathClassHolderSource.class.getClassLoader()); + public ClasspathClassHolderSource(ReferenceCache referenceCache) { + this(ClasspathClassHolderSource.class.getClassLoader(), referenceCache); } @Override diff --git a/core/src/main/java/org/teavm/parsing/DirectoryClasspathClassHolderSource.java b/core/src/main/java/org/teavm/parsing/DirectoryClasspathClassHolderSource.java index 3848e71ea..e04cc2034 100644 --- a/core/src/main/java/org/teavm/parsing/DirectoryClasspathClassHolderSource.java +++ b/core/src/main/java/org/teavm/parsing/DirectoryClasspathClassHolderSource.java @@ -29,16 +29,15 @@ public class DirectoryClasspathClassHolderSource implements ClassHolderSource { private MapperClassHolderSource innerClassSource; private ClasspathResourceMapper classPathMapper; - public DirectoryClasspathClassHolderSource(File baseDir, Properties properties) { - ReferenceCache referenceCache = new ReferenceCache(); + public DirectoryClasspathClassHolderSource(File baseDir, Properties properties, ReferenceCache referenceCache) { DirectoryResourceReader reader = new DirectoryResourceReader(baseDir); ResourceClassHolderMapper rawMapper = new ResourceClassHolderMapper(reader, referenceCache); classPathMapper = new ClasspathResourceMapper(properties, referenceCache, rawMapper); innerClassSource = new MapperClassHolderSource(classPathMapper); } - public DirectoryClasspathClassHolderSource(File baseDir) { - this(baseDir, new Properties()); + public DirectoryClasspathClassHolderSource(File baseDir, ReferenceCache referenceCache) { + this(baseDir, new Properties(), referenceCache); } @Override diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java index 58524739c..1acb76054 100644 --- a/core/src/main/java/org/teavm/vm/TeaVM.java +++ b/core/src/main/java/org/teavm/vm/TeaVM.java @@ -158,7 +158,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { classSource = builder.classSource; classLoader = builder.classLoader; dependencyAnalyzer = builder.dependencyAnalyzerFactory.create(this.classSource, classLoader, - this, diagnostics); + this, diagnostics, builder.referenceCache); progressListener = new TeaVMProgressListener() { @Override public TeaVMProgressFeedback progressReached(int progress) { return TeaVMProgressFeedback.CONTINUE; diff --git a/core/src/main/java/org/teavm/vm/TeaVMBuilder.java b/core/src/main/java/org/teavm/vm/TeaVMBuilder.java index 6b4442449..e2ef88002 100644 --- a/core/src/main/java/org/teavm/vm/TeaVMBuilder.java +++ b/core/src/main/java/org/teavm/vm/TeaVMBuilder.java @@ -19,18 +19,20 @@ import org.teavm.dependency.DependencyAnalyzerFactory; import org.teavm.dependency.PreciseDependencyAnalyzer; import org.teavm.interop.PlatformMarker; import org.teavm.model.ClassReaderSource; +import org.teavm.model.ReferenceCache; import org.teavm.parsing.ClasspathClassHolderSource; public class TeaVMBuilder { TeaVMTarget target; ClassReaderSource classSource; ClassLoader classLoader; + ReferenceCache referenceCache = new ReferenceCache(); DependencyAnalyzerFactory dependencyAnalyzerFactory = PreciseDependencyAnalyzer::new; public TeaVMBuilder(TeaVMTarget target) { this.target = target; classLoader = TeaVMBuilder.class.getClassLoader(); - classSource = !isBootstrap() ? new ClasspathClassHolderSource(classLoader) : name -> null; + classSource = !isBootstrap() ? new ClasspathClassHolderSource(classLoader, referenceCache) : name -> null; } public ClassReaderSource getClassSource() { @@ -60,6 +62,11 @@ public class TeaVMBuilder { return this; } + public TeaVMBuilder setReferenceCache(ReferenceCache referenceCache) { + this.referenceCache = referenceCache; + return this; + } + public TeaVM build() { return new TeaVM(this); } diff --git a/core/src/test/java/org/teavm/cache/ProgramIOTest.java b/core/src/test/java/org/teavm/cache/ProgramIOTest.java index c7d0d3403..a0efe92bf 100644 --- a/core/src/test/java/org/teavm/cache/ProgramIOTest.java +++ b/core/src/test/java/org/teavm/cache/ProgramIOTest.java @@ -25,6 +25,7 @@ import org.junit.Test; import org.teavm.model.BasicBlock; import org.teavm.model.Instruction; import org.teavm.model.Program; +import org.teavm.model.ReferenceCache; import org.teavm.model.ValueType; import org.teavm.model.instructions.*; @@ -157,7 +158,7 @@ public class ProgramIOTest { private Program inputOutput(Program program) { InMemorySymbolTable symbolTable = 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()) { programIO.write(program, output); try (ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray())) { diff --git a/tests/src/test/java/org/teavm/dependency/DependencyTest.java b/tests/src/test/java/org/teavm/dependency/DependencyTest.java index 852363bb5..8419e8883 100644 --- a/tests/src/test/java/org/teavm/dependency/DependencyTest.java +++ b/tests/src/test/java/org/teavm/dependency/DependencyTest.java @@ -39,6 +39,7 @@ import org.teavm.model.Instruction; import org.teavm.model.MethodHolder; import org.teavm.model.MethodReference; import org.teavm.model.Program; +import org.teavm.model.ReferenceCache; import org.teavm.model.TextLocation; import org.teavm.model.ValueType; import org.teavm.model.analysis.ClassInference; @@ -63,7 +64,8 @@ public class DependencyTest { @BeforeClass public static void prepare() { - classSource = new ClasspathClassHolderSource(DependencyTest.class.getClassLoader()); + classSource = new ClasspathClassHolderSource(DependencyTest.class.getClassLoader(), + new ReferenceCache()); } @AfterClass diff --git a/tests/src/test/java/org/teavm/incremental/IncrementalTest.java b/tests/src/test/java/org/teavm/incremental/IncrementalTest.java index 5ba4f665d..782b5cba0 100644 --- a/tests/src/test/java/org/teavm/incremental/IncrementalTest.java +++ b/tests/src/test/java/org/teavm/incremental/IncrementalTest.java @@ -58,6 +58,7 @@ import org.teavm.model.ClassHolderSource; import org.teavm.model.ClassReader; import org.teavm.model.MethodReference; import org.teavm.model.Program; +import org.teavm.model.ReferenceCache; import org.teavm.model.util.ModelUtils; import org.teavm.parsing.ClasspathClassHolderSource; 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 REFRESHED_FILE = "classes-refreshed.js"; private static ClassHolderSource oldClassSource = new ClasspathClassHolderSource( - IncrementalTest.class.getClassLoader()); + IncrementalTest.class.getClassLoader(), new ReferenceCache()); private static Context rhinoContext; private static ScriptableObject rhinoRootScope; private String[] updatedMethods; @@ -238,7 +239,7 @@ public class IncrementalTest { boolean capturing; CapturingMethodNodeCache() { - super(new InMemorySymbolTable(), new InMemorySymbolTable()); + super(new ReferenceCache(), new InMemorySymbolTable(), new InMemorySymbolTable()); } @Override @@ -263,7 +264,7 @@ public class IncrementalTest { boolean capturing; CapturingProgramCache() { - super(new InMemorySymbolTable(), new InMemorySymbolTable()); + super(new ReferenceCache(), new InMemorySymbolTable(), new InMemorySymbolTable()); } @Override diff --git a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java index ba32a9eb9..aa4b10143 100644 --- a/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -53,6 +53,7 @@ import org.teavm.model.ClassHolderSource; import org.teavm.model.ClassHolderTransformer; import org.teavm.model.ClassReader; import org.teavm.model.PreOptimizingClassHolderSource; +import org.teavm.model.ReferenceCache; import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.tooling.sources.SourceFileProvider; import org.teavm.tooling.sources.SourceFilesCopier; @@ -100,6 +101,7 @@ public class TeaVMTool { private CTarget cTarget; private Set generatedFiles = new HashSet<>(); private int minHeapSize = 32 * (1 << 20); + private ReferenceCache referenceCache; public File getTargetDirectory() { return targetDirectory; @@ -299,7 +301,7 @@ public class TeaVMTool { javaScriptTarget.setTopLevelNameLimit(maxTopLevelNames); debugEmitter = debugInformationGenerated || sourceMapsFileGenerated - ? new DebugInformationBuilder() : null; + ? new DebugInformationBuilder(referenceCache) : null; javaScriptTarget.setDebugEmitter(debugEmitter); return javaScriptTarget; @@ -327,17 +329,20 @@ public class TeaVMTool { log.info("Running TeaVM"); TeaVMBuilder vmBuilder = new TeaVMBuilder(prepareTarget()); CacheStatus cacheStatus; + referenceCache = new ReferenceCache(); + vmBuilder.setReferenceCache(referenceCache); if (incremental) { cacheDirectory.mkdirs(); symbolTable = new FileSymbolTable(new File(cacheDirectory, "symbols")); fileTable = new FileSymbolTable(new File(cacheDirectory, "files")); - ClasspathClassHolderSource innerClassSource = new ClasspathClassHolderSource(classLoader); + ClasspathClassHolderSource innerClassSource = new ClasspathClassHolderSource(classLoader, + referenceCache); ClassHolderSource classSource = new PreOptimizingClassHolderSource(innerClassSource); - cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, symbolTable, fileTable, - classSource, innerClassSource); - programCache = new DiskProgramCache(cacheDirectory, symbolTable, fileTable); + cachedClassSource = new DiskCachedClassHolderSource(cacheDirectory, referenceCache, symbolTable, + fileTable, classSource, innerClassSource); + programCache = new DiskProgramCache(cacheDirectory, referenceCache, symbolTable, fileTable); if (incremental && targetType == TeaVMTargetType.JAVASCRIPT) { - astCache = new DiskMethodNodeCache(cacheDirectory, symbolTable, fileTable); + astCache = new DiskMethodNodeCache(cacheDirectory, referenceCache, symbolTable, fileTable); javaScriptTarget.setAstCache(astCache); } try { @@ -350,7 +355,7 @@ public class TeaVMTool { cacheStatus = cachedClassSource; } else { vmBuilder.setClassLoader(classLoader).setClassSource(new PreOptimizingClassHolderSource( - new ClasspathClassHolderSource(classLoader))); + new ClasspathClassHolderSource(classLoader, referenceCache))); cacheStatus = AlwaysStaleCacheStatus.INSTANCE; } diff --git a/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java b/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java index 085bd2f6a..89a65d7b9 100644 --- a/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java +++ b/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java @@ -76,6 +76,7 @@ import org.teavm.debugging.information.DebugInformationBuilder; import org.teavm.dependency.FastDependencyAnalyzer; import org.teavm.model.ClassReader; import org.teavm.model.PreOptimizingClassHolderSource; +import org.teavm.model.ReferenceCache; import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.TeaVMProblemRenderer; @@ -139,6 +140,7 @@ public class CodeServlet extends HttpServlet { private WebSocketClient wsClient = new WebSocketClient(); private InMemorySymbolTable symbolTable = new InMemorySymbolTable(); private InMemorySymbolTable fileSymbolTable = new InMemorySymbolTable(); + private ReferenceCache referenceCache = new ReferenceCache(); public CodeServlet(String mainClass, String[] classPath) { this.mainClass = mainClass; @@ -707,8 +709,8 @@ public class CodeServlet extends HttpServlet { watcher = new FileSystemWatcher(classPath); classSource = new MemoryCachedClassReaderSource(); - astCache = new InMemoryMethodNodeCache(symbolTable, fileSymbolTable); - programCache = new InMemoryProgramCache(symbolTable, fileSymbolTable); + astCache = new InMemoryMethodNodeCache(referenceCache, symbolTable, fileSymbolTable); + programCache = new InMemoryProgramCache(referenceCache, symbolTable, fileSymbolTable); } private void shutdownBuilder() { @@ -733,15 +735,16 @@ public class CodeServlet extends HttpServlet { fireBuildStarted(); reportProgress(0); - DebugInformationBuilder debugInformationBuilder = new DebugInformationBuilder(); + DebugInformationBuilder debugInformationBuilder = new DebugInformationBuilder(referenceCache); ClassLoader classLoader = initClassLoader(); classSource.setUnderlyingSource(new PreOptimizingClassHolderSource( - new ClasspathClassHolderSource(classLoader))); + new ClasspathClassHolderSource(classLoader, referenceCache))); long startTime = System.currentTimeMillis(); JavaScriptTarget jsTarget = new JavaScriptTarget(); TeaVM vm = new TeaVMBuilder(jsTarget) + .setReferenceCache(referenceCache) .setClassLoader(classLoader) .setClassSource(classSource) .setDependencyAnalyzerFactory(FastDependencyAnalyzer::new) diff --git a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java index 4cb70907a..9583e9483 100644 --- a/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java +++ b/tools/junit/src/main/java/org/teavm/junit/TeaVMTestRunner.java @@ -76,6 +76,7 @@ import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodHolder; import org.teavm.model.MethodReference; import org.teavm.model.PreOptimizingClassHolderSource; +import org.teavm.model.ReferenceCache; import org.teavm.model.ValueType; import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.tooling.TeaVMProblemRenderer; @@ -116,6 +117,7 @@ public class TeaVMTestRunner extends Runner implements Filterable { private static ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); private CountDownLatch latch; private List filteredChildren; + private ReferenceCache referenceCache = new ReferenceCache(); static class RunnerKindInfo { volatile TestRunner runner; @@ -559,7 +561,7 @@ public class TeaVMTestRunner extends Runner implements Filterable { private CompileResult compileToJs(Method method, TeaVMTestConfiguration configuration, File path) { boolean decodeStack = Boolean.parseBoolean(System.getProperty(JS_DECODE_STACK, "true")); - DebugInformationBuilder debugEmitter = new DebugInformationBuilder(); + DebugInformationBuilder debugEmitter = new DebugInformationBuilder(new ReferenceCache()); Supplier targetSupplier = () -> { JavaScriptTarget target = new JavaScriptTarget(); if (decodeStack) { @@ -639,6 +641,7 @@ public class TeaVMTestRunner extends Runner implements Filterable { TeaVM vm = new TeaVMBuilder(target) .setClassLoader(classLoader) .setClassSource(classSource) + .setReferenceCache(referenceCache) .setDependencyAnalyzerFactory(dependencyAnalyzerFactory) .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( - new ClasspathClassHolderSource(classLoader))); + new ClasspathClassHolderSource(classLoader, referenceCache))); } @Override