Fixes issues with dependency checking

This commit is contained in:
konsoletyper 2014-01-08 17:48:54 +04:00
parent d844d1cc1d
commit 93e2f5d284
2 changed files with 32 additions and 7 deletions

View File

@ -18,6 +18,7 @@ package org.teavm.dependency;
import java.util.Collection;
import java.util.HashSet;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.teavm.common.ConcurrentCachedMapper;
import org.teavm.common.Mapper;
@ -40,6 +41,8 @@ public class DependencyChecker {
private ConcurrentMap<String, Object> achievableClasses = new ConcurrentHashMap<>();
private ConcurrentMap<String, Object> initializedClasses = new ConcurrentHashMap<>();
private AtomicReference<RuntimeException> exceptionOccured = new AtomicReference<>();
private AtomicInteger activeTaskCount = new AtomicInteger(0);
private final Object activeTaskMonitor = new Object();
public DependencyChecker(ClassHolderSource classSource, ClassLoader classLoader) {
this(classSource, classLoader, Runtime.getRuntime().availableProcessors());
@ -103,15 +106,22 @@ public class DependencyChecker {
}
void schedule(final Runnable runnable) {
activeTaskCount.incrementAndGet();
try {
executor.execute(new Runnable() {
@Override public void run() {
try {
runnable.run();
} catch (RuntimeException e) {
activeTaskMonitor.notifyAll();
exceptionOccured.compareAndSet(null, e);
executor.shutdownNow();
}
if (activeTaskCount.decrementAndGet() == 0) {
synchronized (activeTaskMonitor) {
activeTaskMonitor.notifyAll();
}
}
}
});
} catch (RejectedExecutionException e) {
@ -120,11 +130,13 @@ public class DependencyChecker {
}
public void checkDependencies() {
exceptionOccured.set(null);
while (true) {
if (activeTaskCount.get() == 0 || exceptionOccured.get() != null) {
break;
}
try {
if (executor.getActiveCount() == 0 || executor.awaitTermination(2, TimeUnit.MILLISECONDS)) {
break;
synchronized (activeTaskMonitor) {
activeTaskMonitor.wait();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
@ -138,8 +150,8 @@ public class DependencyChecker {
executor.shutdown();
}
void achieveClass(String className) {
achievableClasses.put(className, dummyValue);
boolean achieveClass(String className) {
return achievableClasses.putIfAbsent(className, dummyValue) == null;
}
public MethodGraph attachMethodGraph(MethodReference methodRef) {
@ -152,6 +164,8 @@ public class DependencyChecker {
if (initializedClasses.putIfAbsent(className, clinitDesc) != null) {
break;
}
achieveClass(className);
achieveInterfaces(className);
ClassHolder cls = classSource.getClassHolder(className);
if (cls == null) {
throw new RuntimeException("Class not found: " + className);
@ -163,6 +177,18 @@ public class DependencyChecker {
}
}
private void achieveInterfaces(String className) {
ClassHolder cls = classSource.getClassHolder(className);
if (cls == null) {
throw new RuntimeException("Class not found: " + className);
}
for (String iface : cls.getInterfaces()) {
if (achieveClass(iface)) {
achieveInterfaces(iface);
}
}
}
private MethodGraph createMethodGraph(final MethodReference methodRef) {
initClass(methodRef.getClassName());
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
@ -202,7 +228,6 @@ public class DependencyChecker {
@Override public void run() {
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
graphBuilder.buildGraph(currentMethod, graph);
achieveClass(methodRef.getClassName());
}
});
return graph;

View File

@ -69,7 +69,6 @@ public class JavascriptBuilder {
}
public void build(Appendable writer) throws RenderingException {
Decompiler decompiler = new Decompiler(classSource, classLoader);
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource);
naming.setMinifying(minifying);
@ -83,6 +82,7 @@ public class JavascriptBuilder {
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
dependencyChecker.checkDependencies();
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
Decompiler decompiler = new Decompiler(classSet, classLoader);
ClassSetOptimizer optimizer = new ClassSetOptimizer();
optimizer.optimizeAll(classSet);
renderer.renderRuntime();