mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-08 07:54:11 -08:00
Removes threading
This commit is contained in:
parent
e60be5d518
commit
7a36799b99
|
@ -69,12 +69,6 @@ public final class TeaVMRunner {
|
||||||
.withDescription("Generate source maps")
|
.withDescription("Generate source maps")
|
||||||
.withLongOpt("sourcemaps")
|
.withLongOpt("sourcemaps")
|
||||||
.create());
|
.create());
|
||||||
options.addOption(OptionBuilder
|
|
||||||
.withArgName("number")
|
|
||||||
.hasArg()
|
|
||||||
.withDescription("how many threads should TeaVM run")
|
|
||||||
.withLongOpt("threads")
|
|
||||||
.create("t"));
|
|
||||||
|
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
printUsage(options);
|
printUsage(options);
|
||||||
|
@ -122,15 +116,6 @@ public final class TeaVMRunner {
|
||||||
if (commandLine.hasOption("mainpage")) {
|
if (commandLine.hasOption("mainpage")) {
|
||||||
tool.setMainPageIncluded(true);
|
tool.setMainPageIncluded(true);
|
||||||
}
|
}
|
||||||
if (commandLine.hasOption("t")) {
|
|
||||||
try {
|
|
||||||
tool.setNumThreads(Integer.parseInt(commandLine.getOptionValue("t")));
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
System.err.println("Wrong parameter for -t option specified");
|
|
||||||
printUsage(options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (commandLine.hasOption('D')) {
|
if (commandLine.hasOption('D')) {
|
||||||
tool.setDebugInformation(new File(tool.getTargetDirectory(), tool.getTargetFileName() + ".teavmdbg"));
|
tool.setDebugInformation(new File(tool.getTargetDirectory(), tool.getTargetFileName() + ".teavmdbg"));
|
||||||
if (commandLine.hasOption("sourcemaps")) {
|
if (commandLine.hasOption("sourcemaps")) {
|
||||||
|
|
|
@ -15,29 +15,23 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.common;
|
package org.teavm.common;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class ConcurrentCachedMapper<T, R> implements Mapper<T, R> {
|
public class CachedMapper<T, R> implements Mapper<T, R> {
|
||||||
private Mapper<T, R> innerMapper;
|
private Mapper<T, R> innerMapper;
|
||||||
private ConcurrentMap<T, Wrapper<R>> cache = new ConcurrentHashMap<>();
|
private Map<T, Wrapper<R>> cache = new HashMap<>();
|
||||||
private List<KeyListener<T>> keyListeners = new ArrayList<>();
|
private List<KeyListener<T>> keyListeners = new ArrayList<>();
|
||||||
|
|
||||||
private static class Wrapper<S> {
|
private static class Wrapper<S> {
|
||||||
volatile S value;
|
S value;
|
||||||
volatile CountDownLatch latch = new CountDownLatch(1);
|
boolean computed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentCachedMapper(Mapper<T, R> innerMapper) {
|
public CachedMapper(Mapper<T, R> innerMapper) {
|
||||||
this.innerMapper = innerMapper;
|
this.innerMapper = innerMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,25 +45,12 @@ public class ConcurrentCachedMapper<T, R> implements Mapper<T, R> {
|
||||||
Wrapper<R> wrapper = cache.get(preimage);
|
Wrapper<R> wrapper = cache.get(preimage);
|
||||||
if (wrapper == null) {
|
if (wrapper == null) {
|
||||||
wrapper = new Wrapper<>();
|
wrapper = new Wrapper<>();
|
||||||
Wrapper<R> oldWrapper = cache.putIfAbsent(preimage, wrapper);
|
cache.put(preimage, wrapper);
|
||||||
if (oldWrapper == null) {
|
wrapper.value = innerMapper.map(preimage);
|
||||||
wrapper.value = innerMapper.map(preimage);
|
wrapper.computed = true;
|
||||||
wrapper.latch.countDown();
|
|
||||||
wrapper.latch = null;
|
|
||||||
for (KeyListener<T> listener : keyListeners) {
|
|
||||||
listener.keyAdded(preimage);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wrapper = oldWrapper;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CountDownLatch latch = wrapper.latch;
|
if (!wrapper.computed) {
|
||||||
if (latch != null) {
|
throw new IllegalStateException("Recursive calls are not allowed");
|
||||||
try {
|
|
||||||
latch.await();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return wrapper.value;
|
return wrapper.value;
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import org.teavm.common.*;
|
import org.teavm.common.*;
|
||||||
import org.teavm.common.ConcurrentCachedMapper.KeyListener;
|
import org.teavm.common.CachedMapper.KeyListener;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.util.ModelUtils;
|
import org.teavm.model.util.ModelUtils;
|
||||||
|
|
||||||
|
@ -34,43 +34,37 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
private int classNameSuffix;
|
private int classNameSuffix;
|
||||||
private DependencyClassSource classSource;
|
private DependencyClassSource classSource;
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private FiniteExecutor executor;
|
|
||||||
private Mapper<MethodReference, MethodReader> methodReaderCache;
|
private Mapper<MethodReference, MethodReader> methodReaderCache;
|
||||||
private Mapper<FieldReference, FieldReader> fieldReaderCache;
|
private Mapper<FieldReference, FieldReader> fieldReaderCache;
|
||||||
private ConcurrentMap<MethodReference, DependencyStack> stacks = new ConcurrentHashMap<>();
|
private ConcurrentMap<MethodReference, DependencyStack> stacks = new ConcurrentHashMap<>();
|
||||||
private ConcurrentMap<FieldReference, DependencyStack> fieldStacks = new ConcurrentHashMap<>();
|
private ConcurrentMap<FieldReference, DependencyStack> fieldStacks = new ConcurrentHashMap<>();
|
||||||
private ConcurrentMap<String, DependencyStack> classStacks = new ConcurrentHashMap<>();
|
private ConcurrentMap<String, DependencyStack> classStacks = new ConcurrentHashMap<>();
|
||||||
private ConcurrentCachedMapper<MethodReference, MethodDependency> methodCache;
|
private CachedMapper<MethodReference, MethodDependency> methodCache;
|
||||||
private ConcurrentCachedMapper<FieldReference, FieldDependency> fieldCache;
|
private CachedMapper<FieldReference, FieldDependency> fieldCache;
|
||||||
private ConcurrentMap<String, Object> achievableClasses = new ConcurrentHashMap<>();
|
private ConcurrentMap<String, Object> achievableClasses = new ConcurrentHashMap<>();
|
||||||
private ConcurrentMap<String, Object> initializedClasses = new ConcurrentHashMap<>();
|
private ConcurrentMap<String, Object> initializedClasses = new ConcurrentHashMap<>();
|
||||||
private List<DependencyListener> listeners = new ArrayList<>();
|
private List<DependencyListener> listeners = new ArrayList<>();
|
||||||
private ServiceRepository services;
|
private ServiceRepository services;
|
||||||
|
private Queue<Runnable> tasks = new ArrayDeque<>();
|
||||||
ConcurrentMap<MethodReference, DependencyStack> missingMethods = new ConcurrentHashMap<>();
|
ConcurrentMap<MethodReference, DependencyStack> missingMethods = new ConcurrentHashMap<>();
|
||||||
ConcurrentMap<String, DependencyStack> missingClasses = new ConcurrentHashMap<>();
|
ConcurrentMap<String, DependencyStack> missingClasses = new ConcurrentHashMap<>();
|
||||||
ConcurrentMap<FieldReference, DependencyStack> missingFields = new ConcurrentHashMap<>();
|
ConcurrentMap<FieldReference, DependencyStack> missingFields = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services) {
|
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services) {
|
||||||
this(classSource, classLoader, services, new SimpleFiniteExecutor());
|
|
||||||
}
|
|
||||||
|
|
||||||
public DependencyChecker(ClassReaderSource classSource, ClassLoader classLoader, ServiceRepository services,
|
|
||||||
FiniteExecutor executor) {
|
|
||||||
this.classSource = new DependencyClassSource(classSource);
|
this.classSource = new DependencyClassSource(classSource);
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
this.executor = executor;
|
|
||||||
this.services = services;
|
this.services = services;
|
||||||
methodReaderCache = new ConcurrentCachedMapper<>(new Mapper<MethodReference, MethodReader>() {
|
methodReaderCache = new CachedMapper<>(new Mapper<MethodReference, MethodReader>() {
|
||||||
@Override public MethodReader map(MethodReference preimage) {
|
@Override public MethodReader map(MethodReference preimage) {
|
||||||
return findMethodReader(preimage);
|
return findMethodReader(preimage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fieldReaderCache = new ConcurrentCachedMapper<>(new Mapper<FieldReference, FieldReader>() {
|
fieldReaderCache = new CachedMapper<>(new Mapper<FieldReference, FieldReader>() {
|
||||||
@Override public FieldReader map(FieldReference preimage) {
|
@Override public FieldReader map(FieldReference preimage) {
|
||||||
return findFieldReader(preimage);
|
return findFieldReader(preimage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
methodCache = new ConcurrentCachedMapper<>(new Mapper<MethodReference, MethodDependency>() {
|
methodCache = new CachedMapper<>(new Mapper<MethodReference, MethodDependency>() {
|
||||||
@Override public MethodDependency map(MethodReference preimage) {
|
@Override public MethodDependency map(MethodReference preimage) {
|
||||||
MethodReader method = methodReaderCache.map(preimage);
|
MethodReader method = methodReaderCache.map(preimage);
|
||||||
if (method != null && !method.getReference().equals(preimage)) {
|
if (method != null && !method.getReference().equals(preimage)) {
|
||||||
|
@ -80,7 +74,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
return createMethodDep(preimage, method, stacks.get(preimage));
|
return createMethodDep(preimage, method, stacks.get(preimage));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
fieldCache = new ConcurrentCachedMapper<>(new Mapper<FieldReference, FieldDependency>() {
|
fieldCache = new CachedMapper<>(new Mapper<FieldReference, FieldDependency>() {
|
||||||
@Override public FieldDependency map(FieldReference preimage) {
|
@Override public FieldDependency map(FieldReference preimage) {
|
||||||
FieldReader field = fieldReaderCache.map(preimage);
|
FieldReader field = fieldReaderCache.map(preimage);
|
||||||
if (field != null && !field.getReference().equals(preimage)) {
|
if (field != null && !field.getReference().equals(preimage)) {
|
||||||
|
@ -162,17 +156,13 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedulePropagation(final DependencyConsumer consumer, final String type) {
|
void schedulePropagation(final DependencyConsumer consumer, final String type) {
|
||||||
executor.executeFast(new Runnable() {
|
tasks.add(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
consumer.consume(type);
|
consumer.consume(type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiniteExecutor getExecutor() {
|
|
||||||
return executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean achieveClass(String className, DependencyStack stack) {
|
boolean achieveClass(String className, DependencyStack stack) {
|
||||||
classStacks.putIfAbsent(className, stack);
|
classStacks.putIfAbsent(className, stack);
|
||||||
boolean result = achievableClasses.putIfAbsent(className, dummyValue) == null;
|
boolean result = achievableClasses.putIfAbsent(className, dummyValue) == null;
|
||||||
|
@ -210,7 +200,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
if (cls.getMethod(clinitDesc) != null) {
|
if (cls.getMethod(clinitDesc) != null) {
|
||||||
final MethodReference methodRef = new MethodReference(className, clinitDesc);
|
final MethodReference methodRef = new MethodReference(className, clinitDesc);
|
||||||
executor.executeFast(new Runnable() {
|
tasks.add(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
linkMethod(methodRef, new DependencyStack(methodRef, stack)).use();
|
linkMethod(methodRef, new DependencyStack(methodRef, stack)).use();
|
||||||
}
|
}
|
||||||
|
@ -309,7 +299,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
final MethodDependency dep = new MethodDependency(parameterNodes, paramCount, resultNode, thrown,
|
final MethodDependency dep = new MethodDependency(parameterNodes, paramCount, resultNode, thrown,
|
||||||
stack, method, methodRef);
|
stack, method, methodRef);
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
executor.execute(new Runnable() {
|
tasks.add(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
||||||
graphBuilder.buildGraph(dep);
|
graphBuilder.buildGraph(dep);
|
||||||
|
@ -320,7 +310,7 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
final DependencyStack callerStack = stack;
|
final DependencyStack callerStack = stack;
|
||||||
executor.execute(new Runnable() {
|
tasks.add(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
initClass(dep.getReference().getClassName(), callerStack);
|
initClass(dep.getReference().getClassName(), callerStack);
|
||||||
}
|
}
|
||||||
|
@ -451,6 +441,12 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void processDependencies() {
|
||||||
|
while (!tasks.isEmpty()) {
|
||||||
|
tasks.poll().run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T getService(Class<T> type) {
|
public <T> T getService(Class<T> type) {
|
||||||
return services.getService(type);
|
return services.getService(type);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import org.teavm.common.ConcurrentCachedMapper;
|
import org.teavm.common.CachedMapper;
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
import org.teavm.model.ClassHolderTransformer;
|
||||||
|
@ -36,7 +36,7 @@ class DependencyClassSource implements ClassReaderSource {
|
||||||
private ClassReaderSource innerSource;
|
private ClassReaderSource innerSource;
|
||||||
private ConcurrentMap<String, ClassHolder> generatedClasses = new ConcurrentHashMap<>();
|
private ConcurrentMap<String, ClassHolder> generatedClasses = new ConcurrentHashMap<>();
|
||||||
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||||
private ConcurrentCachedMapper<String, ClassReader> cache = new ConcurrentCachedMapper<>(
|
private CachedMapper<String, ClassReader> cache = new CachedMapper<>(
|
||||||
new Mapper<String, ClassReader>() {
|
new Mapper<String, ClassReader>() {
|
||||||
@Override public ClassReader map(String preimage) {
|
@Override public ClassReader map(String preimage) {
|
||||||
return findAndTransformClass(preimage);
|
return findAndTransformClass(preimage);
|
||||||
|
|
|
@ -42,14 +42,12 @@ public class Decompiler {
|
||||||
private RangeTree codeTree;
|
private RangeTree codeTree;
|
||||||
private RangeTree.Node currentNode;
|
private RangeTree.Node currentNode;
|
||||||
private RangeTree.Node parentNode;
|
private RangeTree.Node parentNode;
|
||||||
private FiniteExecutor executor;
|
|
||||||
private Map<MethodReference, Generator> generators = new HashMap<>();
|
private Map<MethodReference, Generator> generators = new HashMap<>();
|
||||||
private Set<MethodReference> methodsToPass = new HashSet<>();
|
private Set<MethodReference> methodsToPass = new HashSet<>();
|
||||||
|
|
||||||
public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) {
|
public Decompiler(ClassHolderSource classSource, ClassLoader classLoader) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
this.executor = executor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGraphSize() {
|
public int getGraphSize() {
|
||||||
|
@ -79,18 +77,8 @@ public class Decompiler {
|
||||||
final List<ClassNode> result = new ArrayList<>();
|
final List<ClassNode> result = new ArrayList<>();
|
||||||
for (int i = 0; i < sequence.size(); ++i) {
|
for (int i = 0; i < sequence.size(); ++i) {
|
||||||
final String className = sequence.get(i);
|
final String className = sequence.get(i);
|
||||||
result.add(null);
|
result.add(decompile(classSource.get(className)));
|
||||||
final int index = i;
|
|
||||||
executor.execute(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
Decompiler copy = new Decompiler(classSource, classLoader, executor);
|
|
||||||
copy.generators = generators;
|
|
||||||
copy.methodsToPass = methodsToPass;
|
|
||||||
result.set(index, copy.decompile(classSource.get(className)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
executor.complete();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ package org.teavm.optimization;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ListableClassHolderSource;
|
import org.teavm.model.ListableClassHolderSource;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
|
@ -29,12 +28,6 @@ import org.teavm.model.util.ProgramUtils;
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class ClassSetOptimizer {
|
public class ClassSetOptimizer {
|
||||||
private Executor executor;
|
|
||||||
|
|
||||||
public ClassSetOptimizer(Executor executor) {
|
|
||||||
this.executor = executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<MethodOptimization> getOptimizations() {
|
private List<MethodOptimization> getOptimizations() {
|
||||||
return Arrays.<MethodOptimization>asList(new ArrayUnwrapMotion(), new LoopInvariantMotion(),
|
return Arrays.<MethodOptimization>asList(new ArrayUnwrapMotion(), new LoopInvariantMotion(),
|
||||||
new GlobalValueNumbering(), new UnusedVariableElimination());
|
new GlobalValueNumbering(), new UnusedVariableElimination());
|
||||||
|
@ -43,18 +36,13 @@ public class ClassSetOptimizer {
|
||||||
public void optimizeAll(ListableClassHolderSource classSource) {
|
public void optimizeAll(ListableClassHolderSource classSource) {
|
||||||
for (String className : classSource.getClassNames()) {
|
for (String className : classSource.getClassNames()) {
|
||||||
ClassHolder cls = classSource.get(className);
|
ClassHolder cls = classSource.get(className);
|
||||||
for (final MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
||||||
executor.execute(new Runnable() {
|
Program program = ProgramUtils.copy(method.getProgram());
|
||||||
@Override
|
for (MethodOptimization optimization : getOptimizations()) {
|
||||||
public void run() {
|
optimization.optimize(method, program);
|
||||||
Program program = ProgramUtils.copy(method.getProgram());
|
}
|
||||||
for (MethodOptimization optimization : getOptimizations()) {
|
method.setProgram(program);
|
||||||
optimization.optimize(method, program);
|
|
||||||
}
|
|
||||||
method.setProgram(program);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.common.ConcurrentCachedMapper;
|
import org.teavm.common.CachedMapper;
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class ClasspathResourceMapper implements Mapper<String, ClassHolder> {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Error reading resources", e);
|
throw new RuntimeException("Error reading resources", e);
|
||||||
}
|
}
|
||||||
renamer = new ClassRefsRenamer(new ConcurrentCachedMapper<>(classNameMapper));
|
renamer = new ClassRefsRenamer(new CachedMapper<>(classNameMapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadProperties(Properties properties, Map<String, Transformation> cache) {
|
private void loadProperties(Properties properties, Map<String, Transformation> cache) {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.resource;
|
package org.teavm.resource;
|
||||||
|
|
||||||
import org.teavm.common.ConcurrentCachedMapper;
|
import org.teavm.common.CachedMapper;
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.ClassHolder;
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
|
@ -28,7 +28,7 @@ public class MapperClassHolderSource implements ClassHolderSource {
|
||||||
private Mapper<String, ClassHolder> mapper;
|
private Mapper<String, ClassHolder> mapper;
|
||||||
|
|
||||||
public MapperClassHolderSource(Mapper<String, ClassHolder> mapper) {
|
public MapperClassHolderSource(Mapper<String, ClassHolder> mapper) {
|
||||||
this.mapper = new ConcurrentCachedMapper<>(mapper);
|
this.mapper = new CachedMapper<>(mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -208,7 +208,7 @@ public class TeaVMTestTool {
|
||||||
log.debug("Building test for " + method);
|
log.debug("Building test for " + method);
|
||||||
try {
|
try {
|
||||||
decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource), method,
|
decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource), method,
|
||||||
fileNames.get(method), new SimpleFiniteExecutor());
|
fileNames.get(method));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Error generating JavaScript", e);
|
log.error("Error generating JavaScript", e);
|
||||||
}
|
}
|
||||||
|
@ -275,11 +275,10 @@ public class TeaVMTestTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
||||||
MethodReference methodRef, String targetName, FiniteExecutor executor) throws IOException {
|
MethodReference methodRef, String targetName) throws IOException {
|
||||||
TeaVM vm = new TeaVMBuilder()
|
TeaVM vm = new TeaVMBuilder()
|
||||||
.setClassLoader(classLoader)
|
.setClassLoader(classLoader)
|
||||||
.setClassSource(classSource)
|
.setClassSource(classSource)
|
||||||
.setExecutor(executor)
|
|
||||||
.build();
|
.build();
|
||||||
vm.setProperties(properties);
|
vm.setProperties(properties);
|
||||||
vm.setMinifying(minifying);
|
vm.setMinifying(minifying);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.teavm.common.ThreadPoolFiniteExecutor;
|
|
||||||
import org.teavm.debugging.information.DebugInformation;
|
import org.teavm.debugging.information.DebugInformation;
|
||||||
import org.teavm.debugging.information.DebugInformationBuilder;
|
import org.teavm.debugging.information.DebugInformationBuilder;
|
||||||
import org.teavm.javascript.RenderingContext;
|
import org.teavm.javascript.RenderingContext;
|
||||||
|
@ -48,7 +47,6 @@ public class TeaVMTool {
|
||||||
private File debugInformation;
|
private File debugInformation;
|
||||||
private String sourceMapsFileName;
|
private String sourceMapsFileName;
|
||||||
private boolean sourceMapsFileGenerated;
|
private boolean sourceMapsFileGenerated;
|
||||||
private int numThreads = 1;
|
|
||||||
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
||||||
private List<ClassAlias> classAliases = new ArrayList<>();
|
private List<ClassAlias> classAliases = new ArrayList<>();
|
||||||
private List<MethodAlias> methodAliases = new ArrayList<>();
|
private List<MethodAlias> methodAliases = new ArrayList<>();
|
||||||
|
@ -119,14 +117,6 @@ public class TeaVMTool {
|
||||||
this.debugInformation = debugInformation;
|
this.debugInformation = debugInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumThreads() {
|
|
||||||
return numThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNumThreads(int numThreads) {
|
|
||||||
this.numThreads = numThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSourceMapsFileName() {
|
public String getSourceMapsFileName() {
|
||||||
return sourceMapsFileName;
|
return sourceMapsFileName;
|
||||||
}
|
}
|
||||||
|
@ -176,21 +166,10 @@ public class TeaVMTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate() throws TeaVMToolException {
|
public void generate() throws TeaVMToolException {
|
||||||
Runnable finalizer = null;
|
|
||||||
try {
|
try {
|
||||||
log.info("Building JavaScript file");
|
log.info("Building JavaScript file");
|
||||||
TeaVMBuilder vmBuilder = new TeaVMBuilder();
|
TeaVMBuilder vmBuilder = new TeaVMBuilder();
|
||||||
vmBuilder.setClassLoader(classLoader).setClassSource(new ClasspathClassHolderSource(classLoader));
|
vmBuilder.setClassLoader(classLoader).setClassSource(new ClasspathClassHolderSource(classLoader));
|
||||||
if (numThreads != 1) {
|
|
||||||
int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors();
|
|
||||||
final ThreadPoolFiniteExecutor executor = new ThreadPoolFiniteExecutor(threads);
|
|
||||||
finalizer = new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
executor.stop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
vmBuilder.setExecutor(executor);
|
|
||||||
}
|
|
||||||
TeaVM vm = vmBuilder.build();
|
TeaVM vm = vmBuilder.build();
|
||||||
vm.setMinifying(minifying);
|
vm.setMinifying(minifying);
|
||||||
vm.setBytecodeLogging(bytecodeLogging);
|
vm.setBytecodeLogging(bytecodeLogging);
|
||||||
|
@ -272,10 +251,6 @@ public class TeaVMTool {
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new TeaVMToolException("IO error occured", e);
|
throw new TeaVMToolException("IO error occured", e);
|
||||||
} finally {
|
|
||||||
if (finalizer != null) {
|
|
||||||
finalizer.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.teavm.vm;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.codegen.*;
|
import org.teavm.codegen.*;
|
||||||
import org.teavm.common.FiniteExecutor;
|
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||||
import org.teavm.debugging.information.SourceLocation;
|
import org.teavm.debugging.information.SourceLocation;
|
||||||
|
@ -71,7 +70,6 @@ import org.teavm.vm.spi.TeaVMPlugin;
|
||||||
public class TeaVM implements TeaVMHost, ServiceRepository {
|
public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
private ClassReaderSource classSource;
|
private ClassReaderSource classSource;
|
||||||
private DependencyChecker dependencyChecker;
|
private DependencyChecker dependencyChecker;
|
||||||
private FiniteExecutor executor;
|
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private boolean minifying = true;
|
private boolean minifying = true;
|
||||||
private boolean bytecodeLogging;
|
private boolean bytecodeLogging;
|
||||||
|
@ -85,11 +83,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
private DebugInformationEmitter debugEmitter;
|
private DebugInformationEmitter debugEmitter;
|
||||||
|
|
||||||
TeaVM(ClassReaderSource classSource, ClassLoader classLoader, FiniteExecutor executor) {
|
TeaVM(ClassReaderSource classSource, ClassLoader classLoader) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this, executor);
|
dependencyChecker = new DependencyChecker(this.classSource, classLoader, this);
|
||||||
this.executor = executor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -307,7 +304,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
DependencyStack.ROOT).use();
|
DependencyStack.ROOT).use();
|
||||||
dependencyChecker.linkMethod(new MethodReference("java.lang.Object", new MethodDescriptor("clone",
|
dependencyChecker.linkMethod(new MethodReference("java.lang.Object", new MethodDescriptor("clone",
|
||||||
ValueType.object("java.lang.Object"))), DependencyStack.ROOT).use();
|
ValueType.object("java.lang.Object"))), DependencyStack.ROOT).use();
|
||||||
executor.complete();
|
dependencyChecker.processDependencies();
|
||||||
if (hasMissingItems()) {
|
if (hasMissingItems()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -318,12 +315,9 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
|
|
||||||
// Optimize and allocate registers
|
// Optimize and allocate registers
|
||||||
devirtualize(classSet, dependencyChecker);
|
devirtualize(classSet, dependencyChecker);
|
||||||
executor.complete();
|
ClassSetOptimizer optimizer = new ClassSetOptimizer();
|
||||||
ClassSetOptimizer optimizer = new ClassSetOptimizer(executor);
|
|
||||||
optimizer.optimizeAll(classSet);
|
optimizer.optimizeAll(classSet);
|
||||||
executor.complete();
|
|
||||||
allocateRegisters(classSet);
|
allocateRegisters(classSet);
|
||||||
executor.complete();
|
|
||||||
if (bytecodeLogging) {
|
if (bytecodeLogging) {
|
||||||
try {
|
try {
|
||||||
logBytecode(new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")), classSet);
|
logBytecode(new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")), classSet);
|
||||||
|
@ -333,7 +327,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompile
|
// Decompile
|
||||||
Decompiler decompiler = new Decompiler(classSet, classLoader, executor);
|
Decompiler decompiler = new Decompiler(classSet, classLoader);
|
||||||
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
||||||
decompiler.addGenerator(entry.getKey(), entry.getValue());
|
decompiler.addGenerator(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
@ -421,11 +415,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
for (final MethodHolder method : cls.getMethods()) {
|
for (final MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getProgram() != null) {
|
if (method.getProgram() != null) {
|
||||||
executor.execute(new Runnable() {
|
devirtualization.apply(method);
|
||||||
@Override public void run() {
|
|
||||||
devirtualization.apply(method);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,14 +426,10 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
ClassHolder cls = classes.get(className);
|
ClassHolder cls = classes.get(className);
|
||||||
for (final MethodHolder method : cls.getMethods()) {
|
for (final MethodHolder method : cls.getMethods()) {
|
||||||
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) {
|
||||||
executor.execute(new Runnable() {
|
RegisterAllocator allocator = new RegisterAllocator();
|
||||||
@Override public void run() {
|
Program program = ProgramUtils.copy(method.getProgram());
|
||||||
RegisterAllocator allocator = new RegisterAllocator();
|
allocator.allocateRegisters(method, program);
|
||||||
Program program = ProgramUtils.copy(method.getProgram());
|
method.setProgram(program);
|
||||||
allocator.allocateRegisters(method, program);
|
|
||||||
method.setProgram(program);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.vm;
|
package org.teavm.vm;
|
||||||
|
|
||||||
import org.teavm.common.FiniteExecutor;
|
|
||||||
import org.teavm.common.SimpleFiniteExecutor;
|
|
||||||
import org.teavm.model.ClassHolderSource;
|
import org.teavm.model.ClassHolderSource;
|
||||||
import org.teavm.parsing.ClasspathClassHolderSource;
|
import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
|
|
||||||
|
@ -27,7 +25,6 @@ import org.teavm.parsing.ClasspathClassHolderSource;
|
||||||
public class TeaVMBuilder {
|
public class TeaVMBuilder {
|
||||||
ClassHolderSource classSource;
|
ClassHolderSource classSource;
|
||||||
ClassLoader classLoader;
|
ClassLoader classLoader;
|
||||||
FiniteExecutor executor = new SimpleFiniteExecutor();
|
|
||||||
|
|
||||||
public TeaVMBuilder() {
|
public TeaVMBuilder() {
|
||||||
classLoader = TeaVMBuilder.class.getClassLoader();
|
classLoader = TeaVMBuilder.class.getClassLoader();
|
||||||
|
@ -52,16 +49,7 @@ public class TeaVMBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FiniteExecutor getExecutor() {
|
|
||||||
return executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TeaVMBuilder setExecutor(FiniteExecutor executor) {
|
|
||||||
this.executor = executor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TeaVM build() {
|
public TeaVM build() {
|
||||||
return new TeaVM(classSource, classLoader, executor);
|
return new TeaVM(classSource, classLoader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,9 +80,6 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
@Parameter
|
@Parameter
|
||||||
private File debugInformationFile;
|
private File debugInformationFile;
|
||||||
|
|
||||||
@Parameter(required = false)
|
|
||||||
private int numThreads = 1;
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private String[] transformers;
|
private String[] transformers;
|
||||||
|
|
||||||
|
@ -126,10 +123,6 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
this.mainPageIncluded = mainPageIncluded;
|
this.mainPageIncluded = mainPageIncluded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumThreads(int numThreads) {
|
|
||||||
this.numThreads = numThreads;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getTransformers() {
|
public String[] getTransformers() {
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +170,6 @@ public class BuildJavascriptMojo extends AbstractMojo {
|
||||||
tool.setMainClass(mainClass);
|
tool.setMainClass(mainClass);
|
||||||
tool.setMainPageIncluded(mainPageIncluded);
|
tool.setMainPageIncluded(mainPageIncluded);
|
||||||
tool.setMinifying(minifying);
|
tool.setMinifying(minifying);
|
||||||
tool.setNumThreads(numThreads);
|
|
||||||
tool.setRuntime(runtime);
|
tool.setRuntime(runtime);
|
||||||
tool.setTargetDirectory(targetDirectory);
|
tool.setTargetDirectory(targetDirectory);
|
||||||
tool.setTargetFileName(targetFileName);
|
tool.setTargetFileName(targetFileName);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user