mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Fixes issues with dependency checking
This commit is contained in:
parent
d844d1cc1d
commit
93e2f5d284
|
@ -18,6 +18,7 @@ package org.teavm.dependency;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.teavm.common.ConcurrentCachedMapper;
|
import org.teavm.common.ConcurrentCachedMapper;
|
||||||
import org.teavm.common.Mapper;
|
import org.teavm.common.Mapper;
|
||||||
|
@ -40,6 +41,8 @@ public class DependencyChecker {
|
||||||
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 AtomicReference<RuntimeException> exceptionOccured = new AtomicReference<>();
|
private AtomicReference<RuntimeException> exceptionOccured = new AtomicReference<>();
|
||||||
|
private AtomicInteger activeTaskCount = new AtomicInteger(0);
|
||||||
|
private final Object activeTaskMonitor = new Object();
|
||||||
|
|
||||||
public DependencyChecker(ClassHolderSource classSource, ClassLoader classLoader) {
|
public DependencyChecker(ClassHolderSource classSource, ClassLoader classLoader) {
|
||||||
this(classSource, classLoader, Runtime.getRuntime().availableProcessors());
|
this(classSource, classLoader, Runtime.getRuntime().availableProcessors());
|
||||||
|
@ -103,15 +106,22 @@ public class DependencyChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedule(final Runnable runnable) {
|
void schedule(final Runnable runnable) {
|
||||||
|
activeTaskCount.incrementAndGet();
|
||||||
try {
|
try {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
try {
|
try {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
|
activeTaskMonitor.notifyAll();
|
||||||
exceptionOccured.compareAndSet(null, e);
|
exceptionOccured.compareAndSet(null, e);
|
||||||
executor.shutdownNow();
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
if (activeTaskCount.decrementAndGet() == 0) {
|
||||||
|
synchronized (activeTaskMonitor) {
|
||||||
|
activeTaskMonitor.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (RejectedExecutionException e) {
|
} catch (RejectedExecutionException e) {
|
||||||
|
@ -120,12 +130,14 @@ public class DependencyChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkDependencies() {
|
public void checkDependencies() {
|
||||||
exceptionOccured.set(null);
|
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
if (activeTaskCount.get() == 0 || exceptionOccured.get() != null) {
|
||||||
if (executor.getActiveCount() == 0 || executor.awaitTermination(2, TimeUnit.MILLISECONDS)) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
synchronized (activeTaskMonitor) {
|
||||||
|
activeTaskMonitor.wait();
|
||||||
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
break;
|
break;
|
||||||
|
@ -138,8 +150,8 @@ public class DependencyChecker {
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void achieveClass(String className) {
|
boolean achieveClass(String className) {
|
||||||
achievableClasses.put(className, dummyValue);
|
return achievableClasses.putIfAbsent(className, dummyValue) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodGraph attachMethodGraph(MethodReference methodRef) {
|
public MethodGraph attachMethodGraph(MethodReference methodRef) {
|
||||||
|
@ -152,6 +164,8 @@ public class DependencyChecker {
|
||||||
if (initializedClasses.putIfAbsent(className, clinitDesc) != null) {
|
if (initializedClasses.putIfAbsent(className, clinitDesc) != null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
achieveClass(className);
|
||||||
|
achieveInterfaces(className);
|
||||||
ClassHolder cls = classSource.getClassHolder(className);
|
ClassHolder cls = classSource.getClassHolder(className);
|
||||||
if (cls == null) {
|
if (cls == null) {
|
||||||
throw new RuntimeException("Class not found: " + className);
|
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) {
|
private MethodGraph createMethodGraph(final MethodReference methodRef) {
|
||||||
initClass(methodRef.getClassName());
|
initClass(methodRef.getClassName());
|
||||||
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
ClassHolder cls = classSource.getClassHolder(methodRef.getClassName());
|
||||||
|
@ -202,7 +228,6 @@ public class DependencyChecker {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
DependencyGraphBuilder graphBuilder = new DependencyGraphBuilder(DependencyChecker.this);
|
||||||
graphBuilder.buildGraph(currentMethod, graph);
|
graphBuilder.buildGraph(currentMethod, graph);
|
||||||
achieveClass(methodRef.getClassName());
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return graph;
|
return graph;
|
||||||
|
|
|
@ -69,7 +69,6 @@ public class JavascriptBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void build(Appendable writer) throws RenderingException {
|
public void build(Appendable writer) throws RenderingException {
|
||||||
Decompiler decompiler = new Decompiler(classSource, classLoader);
|
|
||||||
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
AliasProvider aliasProvider = minifying ? new MinifyingAliasProvider() : new DefaultAliasProvider();
|
||||||
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource);
|
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, classSource);
|
||||||
naming.setMinifying(minifying);
|
naming.setMinifying(minifying);
|
||||||
|
@ -83,6 +82,7 @@ public class JavascriptBuilder {
|
||||||
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
||||||
dependencyChecker.checkDependencies();
|
dependencyChecker.checkDependencies();
|
||||||
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
||||||
|
Decompiler decompiler = new Decompiler(classSet, classLoader);
|
||||||
ClassSetOptimizer optimizer = new ClassSetOptimizer();
|
ClassSetOptimizer optimizer = new ClassSetOptimizer();
|
||||||
optimizer.optimizeAll(classSet);
|
optimizer.optimizeAll(classSet);
|
||||||
renderer.renderRuntime();
|
renderer.renderRuntime();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user