mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-31 12:24:10 -08:00
Support of multithreaded execution. Performance optimizations.
This commit is contained in:
parent
0c240f5636
commit
24921c6e80
|
@ -53,7 +53,7 @@
|
||||||
<phase>process-test-classes</phase>
|
<phase>process-test-classes</phase>
|
||||||
<configuration>
|
<configuration>
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<numThreads>1</numThreads>
|
<numThreads>0</numThreads>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
|
@ -66,17 +66,19 @@ public class ThreadPoolFiniteExecutor implements FiniteExecutor {
|
||||||
@Override
|
@Override
|
||||||
public void complete() {
|
public void complete() {
|
||||||
synchronized (monitor) {
|
synchronized (monitor) {
|
||||||
try {
|
while (true) {
|
||||||
monitor.wait();
|
if (thrownException.get() != null) {
|
||||||
} catch (InterruptedException e) {
|
throw thrownException.get();
|
||||||
Thread.currentThread().interrupt();
|
}
|
||||||
return;
|
if (runningTasks.get() == 0) {
|
||||||
}
|
return;
|
||||||
if (thrownException.get() != null) {
|
}
|
||||||
throw thrownException.get();
|
try {
|
||||||
}
|
monitor.wait();
|
||||||
if (runningTasks.get() == 0) {
|
} catch (InterruptedException e) {
|
||||||
return;
|
Thread.currentThread().interrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,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;
|
||||||
|
|
||||||
public Decompiler(ClassHolderSource classSource, ClassLoader classLoader) {
|
public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGraphSize() {
|
public int getGraphSize() {
|
||||||
|
@ -70,10 +72,19 @@ public class Decompiler {
|
||||||
for (String className : classNames) {
|
for (String className : classNames) {
|
||||||
orderClasses(className, visited, sequence);
|
orderClasses(className, visited, sequence);
|
||||||
}
|
}
|
||||||
List<ClassNode> result = new ArrayList<>();
|
final List<ClassNode> result = new ArrayList<>();
|
||||||
for (String className : sequence) {
|
for (int i = 0; i < sequence.size(); ++i) {
|
||||||
result.add(decompile(classSource.getClassHolder(className)));
|
final String className = sequence.get(i);
|
||||||
|
result.add(null);
|
||||||
|
final int index = i;
|
||||||
|
executor.execute(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
Decompiler copy = new Decompiler(classSource, classLoader, executor);
|
||||||
|
result.set(index, copy.decompile(classSource.getClassHolder(className)));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
executor.complete();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ public class JavascriptBuilder {
|
||||||
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
ValueType.arrayOf(ValueType.CHARACTER), ValueType.VOID)));
|
||||||
executor.complete();
|
executor.complete();
|
||||||
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses();
|
||||||
Decompiler decompiler = new Decompiler(classSet, classLoader);
|
Decompiler decompiler = new Decompiler(classSet, classLoader, executor);
|
||||||
ClassSetOptimizer optimizer = new ClassSetOptimizer(executor);
|
ClassSetOptimizer optimizer = new ClassSetOptimizer(executor);
|
||||||
optimizer.optimizeAll(classSet);
|
optimizer.optimizeAll(classSet);
|
||||||
executor.complete();
|
executor.complete();
|
||||||
|
@ -143,7 +143,9 @@ public class JavascriptBuilder {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
RegisterAllocator allocator = new RegisterAllocator();
|
RegisterAllocator allocator = new RegisterAllocator();
|
||||||
allocator.allocateRegisters(method);
|
Program program = ProgramUtils.copy(method.getProgram());
|
||||||
|
allocator.allocateRegisters(method, program);
|
||||||
|
method.setProgram(program);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -208,7 +210,7 @@ public class JavascriptBuilder {
|
||||||
writer.print("byte");
|
writer.print("byte");
|
||||||
break;
|
break;
|
||||||
case CHARACTER:
|
case CHARACTER:
|
||||||
writer.print("character");
|
writer.print("char");
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case DOUBLE:
|
||||||
writer.print("double");
|
writer.print("double");
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model;
|
package org.teavm.model;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,18 +23,18 @@ import java.util.List;
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class AnnotationValue {
|
public class AnnotationValue {
|
||||||
private static final byte BOOLEAN = 0;
|
public static final byte BOOLEAN = 0;
|
||||||
private static final byte BYTE = 1;
|
public static final byte BYTE = 1;
|
||||||
private static final byte SHORT = 2;
|
public static final byte SHORT = 2;
|
||||||
private static final byte INT = 3;
|
public static final byte INT = 3;
|
||||||
private static final byte LONG = 4;
|
public static final byte LONG = 4;
|
||||||
private static final byte FLOAT = 5;
|
public static final byte FLOAT = 5;
|
||||||
private static final byte DOUBLE = 6;
|
public static final byte DOUBLE = 6;
|
||||||
private static final byte STRING = 7;
|
public static final byte STRING = 7;
|
||||||
private static final byte CLASS = 8;
|
public static final byte CLASS = 8;
|
||||||
private static final byte LIST = 9;
|
public static final byte LIST = 9;
|
||||||
private static final byte ENUM = 10;
|
public static final byte ENUM = 10;
|
||||||
private static final byte ANNOTATION = 11;
|
public static final byte ANNOTATION = 11;
|
||||||
private byte type;
|
private byte type;
|
||||||
private Object value;
|
private Object value;
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ public class AnnotationValue {
|
||||||
if (type != LIST) {
|
if (type != LIST) {
|
||||||
throw new IllegalStateException("There is no List value");
|
throw new IllegalStateException("There is no List value");
|
||||||
}
|
}
|
||||||
return (List<AnnotationValue>)value;
|
return Collections.unmodifiableList((List<AnnotationValue>)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldReference getEnumValue() {
|
public FieldReference getEnumValue() {
|
||||||
|
@ -181,4 +182,8 @@ public class AnnotationValue {
|
||||||
}
|
}
|
||||||
return (AnnotationHolder)value;
|
return (AnnotationHolder)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.teavm.common.Mapper;
|
||||||
|
import org.teavm.model.resource.MapperClassHolderSource;
|
||||||
|
import org.teavm.model.util.ProgramUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class CopyClassHolderSource implements ClassHolderSource {
|
||||||
|
private ClassHolderSource innerSource;
|
||||||
|
private MapperClassHolderSource mapperSource = new MapperClassHolderSource(new Mapper<String, ClassHolder>() {
|
||||||
|
@Override public ClassHolder map(String preimage) {
|
||||||
|
return copyClass(preimage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public CopyClassHolderSource(ClassHolderSource innerSource) {
|
||||||
|
this.innerSource = innerSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassHolder getClassHolder(String name) {
|
||||||
|
return mapperSource.getClassHolder(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClassHolder copyClass(String className) {
|
||||||
|
ClassHolder original = innerSource.getClassHolder(className);
|
||||||
|
if (original == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ClassHolder copy = new ClassHolder(className);
|
||||||
|
copy.setLevel(original.getLevel());
|
||||||
|
copy.getModifiers().addAll(original.getModifiers());
|
||||||
|
copy.setParent(original.getParent());
|
||||||
|
copy.getInterfaces().addAll(original.getInterfaces());
|
||||||
|
for (MethodHolder method : original.getMethods()) {
|
||||||
|
copy.addMethod(copyMethod(method));
|
||||||
|
}
|
||||||
|
for (FieldHolder field : original.getFields()) {
|
||||||
|
copy.addField(copyField(field));
|
||||||
|
}
|
||||||
|
copyAnnotations(original.getAnnotations(), copy.getAnnotations());
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MethodHolder copyMethod(MethodHolder method) {
|
||||||
|
MethodHolder copy = new MethodHolder(method.getDescriptor());
|
||||||
|
copy.setLevel(method.getLevel());
|
||||||
|
copy.getModifiers().addAll(method.getModifiers());
|
||||||
|
copy.setProgram(ProgramUtils.copy(method.getProgram()));
|
||||||
|
copyAnnotations(method.getAnnotations(), copy.getAnnotations());
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FieldHolder copyField(FieldHolder field) {
|
||||||
|
FieldHolder copy = new FieldHolder(field.getName());
|
||||||
|
copy.setLevel(field.getLevel());
|
||||||
|
copy.getModifiers().addAll(field.getModifiers());
|
||||||
|
copy.setType(field.getType());
|
||||||
|
copy.setInitialValue(field.getInitialValue());
|
||||||
|
copyAnnotations(field.getAnnotations(), copy.getAnnotations());
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyAnnotations(AnnotationContainer src, AnnotationContainer dst) {
|
||||||
|
for (AnnotationHolder annot : src.all()) {
|
||||||
|
dst.add(copyAnnotation(annot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnotationHolder copyAnnotation(AnnotationHolder annot) {
|
||||||
|
AnnotationHolder copy = new AnnotationHolder(annot.getType());
|
||||||
|
for (Map.Entry<String, AnnotationValue> entry : annot.getValues().entrySet()) {
|
||||||
|
copy.getValues().put(entry.getKey(), copyAnnotationValue(entry.getValue()));
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnotationValue copyAnnotationValue(AnnotationValue value) {
|
||||||
|
switch (value.getType()) {
|
||||||
|
case AnnotationValue.LIST: {
|
||||||
|
List<AnnotationValue> listCopy = new ArrayList<>();
|
||||||
|
for (AnnotationValue item : value.getList()) {
|
||||||
|
listCopy.add(copyAnnotationValue(item));
|
||||||
|
}
|
||||||
|
return new AnnotationValue(listCopy);
|
||||||
|
}
|
||||||
|
case AnnotationValue.ANNOTATION:
|
||||||
|
return new AnnotationValue(copyAnnotation(value.getAnnotation()));
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -48,10 +48,10 @@ public class ProgramUtils {
|
||||||
CopyVisitor insnCopier = new CopyVisitor();
|
CopyVisitor insnCopier = new CopyVisitor();
|
||||||
insnCopier.programCopy = copy;
|
insnCopier.programCopy = copy;
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
program.createVariable();
|
copy.createVariable();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
program.createBasicBlock();
|
copy.createBasicBlock();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
@ -346,7 +346,7 @@ public class ProgramUtils {
|
||||||
insnCopy.setMethod(insn.getMethod());
|
insnCopy.setMethod(insn.getMethod());
|
||||||
insnCopy.setType(insn.getType());
|
insnCopy.setType(insn.getType());
|
||||||
insnCopy.setInstance(insn.getInstance() != null ? copyVar(insn.getInstance()) : null);
|
insnCopy.setInstance(insn.getInstance() != null ? copyVar(insn.getInstance()) : null);
|
||||||
insnCopy.setReceiver(copyVar(insn.getReceiver()));
|
insnCopy.setReceiver(insn.getReceiver() != null ? copyVar(insn.getReceiver()) : null);
|
||||||
for (Variable arg : insn.getArguments()) {
|
for (Variable arg : insn.getArguments()) {
|
||||||
insnCopy.getArguments().add(copyVar(arg));
|
insnCopy.getArguments().add(copyVar(arg));
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,7 @@ import org.teavm.model.instructions.JumpInstruction;
|
||||||
* @author Alexey Andreev
|
* @author Alexey Andreev
|
||||||
*/
|
*/
|
||||||
public class RegisterAllocator {
|
public class RegisterAllocator {
|
||||||
public void allocateRegisters(MethodHolder method) {
|
public void allocateRegisters(MethodReader method, Program program) {
|
||||||
Program program = method.getProgram();
|
|
||||||
List<PhiArgumentCopy> phiArgsCopies = insertPhiArgumentsCopies(program);
|
List<PhiArgumentCopy> phiArgsCopies = insertPhiArgumentsCopies(program);
|
||||||
InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder();
|
InterferenceGraphBuilder interferenceBuilder = new InterferenceGraphBuilder();
|
||||||
LivenessAnalyzer liveness = new LivenessAnalyzer();
|
LivenessAnalyzer liveness = new LivenessAnalyzer();
|
||||||
|
@ -46,7 +45,7 @@ public class RegisterAllocator {
|
||||||
GraphColorer colorer = new GraphColorer();
|
GraphColorer colorer = new GraphColorer();
|
||||||
colorer.colorize(interferenceGraph, classArray, colors);
|
colorer.colorize(interferenceGraph, classArray, colors);
|
||||||
for (int i = 0; i < colors.length; ++i) {
|
for (int i = 0; i < colors.length; ++i) {
|
||||||
method.getProgram().variableAt(i).setRegister(colors[i]);
|
program.variableAt(i).setRegister(colors[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,21 +21,24 @@ 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;
|
||||||
|
import org.teavm.model.Program;
|
||||||
|
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 List<MethodOptimization> optimizations = Arrays.<MethodOptimization>asList(
|
|
||||||
new CommonSubexpressionElimination(), new UnusedVariableElimination());
|
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
|
|
||||||
public ClassSetOptimizer(Executor executor) {
|
public ClassSetOptimizer(Executor executor) {
|
||||||
super();
|
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<MethodOptimization> getOptimizations() {
|
||||||
|
return Arrays.<MethodOptimization>asList(new CommonSubexpressionElimination(), new UnusedVariableElimination());
|
||||||
|
}
|
||||||
|
|
||||||
public void optimizeAll(ListableClassHolderSource classSource) {
|
public void optimizeAll(ListableClassHolderSource classSource) {
|
||||||
for (String className : classSource.getClassNames()) {
|
for (String className : classSource.getClassNames()) {
|
||||||
ClassHolder cls = classSource.getClassHolder(className);
|
ClassHolder cls = classSource.getClassHolder(className);
|
||||||
|
@ -44,9 +47,11 @@ public class ClassSetOptimizer {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for (MethodOptimization optimization : optimizations) {
|
Program program = ProgramUtils.copy(method.getProgram());
|
||||||
optimization.optimize(method);
|
for (MethodOptimization optimization : getOptimizations()) {
|
||||||
|
optimization.optimize(method, program);
|
||||||
}
|
}
|
||||||
|
method.setProgram(program);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,10 +42,10 @@ public class CommonSubexpressionElimination implements MethodOptimization {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void optimize(MethodHolder method) {
|
public void optimize(MethodReader method, Program program) {
|
||||||
program = method.getProgram();
|
this.program = program;
|
||||||
knownValues.clear();
|
knownValues.clear();
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(method.getProgram());
|
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
domTree = GraphUtils.buildDominatorTree(cfg);
|
domTree = GraphUtils.buildDominatorTree(cfg);
|
||||||
Graph dom = GraphUtils.buildDominatorGraph(domTree, cfg.size());
|
Graph dom = GraphUtils.buildDominatorGraph(domTree, cfg.size());
|
||||||
map = new int[program.variableCount()];
|
map = new int[program.variableCount()];
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
package org.teavm.optimization;
|
package org.teavm.optimization;
|
||||||
|
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
import org.teavm.model.instructions.JumpInstruction;
|
import org.teavm.model.instructions.JumpInstruction;
|
||||||
import org.teavm.model.util.BasicBlockMapper;
|
import org.teavm.model.util.BasicBlockMapper;
|
||||||
|
@ -27,8 +27,7 @@ import org.teavm.model.util.BasicBlockMapper;
|
||||||
*/
|
*/
|
||||||
public class EmptyBlockElimination implements MethodOptimization {
|
public class EmptyBlockElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void optimize(MethodHolder method) {
|
public void optimize(MethodReader method, final Program program) {
|
||||||
final Program program = method.getProgram();
|
|
||||||
final int[] blockMapping = new int[program.basicBlockCount()];
|
final int[] blockMapping = new int[program.basicBlockCount()];
|
||||||
for (int i = 0; i < blockMapping.length; ++i) {
|
for (int i = 0; i < blockMapping.length; ++i) {
|
||||||
blockMapping[i] = i;
|
blockMapping[i] = i;
|
||||||
|
|
|
@ -15,12 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.optimization;
|
package org.teavm.optimization;
|
||||||
|
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodReader;
|
||||||
|
import org.teavm.model.Program;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public interface MethodOptimization {
|
public interface MethodOptimization {
|
||||||
void optimize(MethodHolder method);
|
void optimize(MethodReader method, Program program);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ import org.teavm.model.instructions.*;
|
||||||
*/
|
*/
|
||||||
public class UnusedVariableElimination implements MethodOptimization {
|
public class UnusedVariableElimination implements MethodOptimization {
|
||||||
@Override
|
@Override
|
||||||
public void optimize(MethodHolder method) {
|
public void optimize(MethodReader method, Program program) {
|
||||||
if (method.getProgram() == null) {
|
if (method.getProgram() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Graph graph = VariableUsageGraphBuilder.build(method.getProgram());
|
Graph graph = VariableUsageGraphBuilder.build(program);
|
||||||
boolean[] escaping = VariableEscapeAnalyzer.findEscapingVariables(method.getProgram());
|
boolean[] escaping = VariableEscapeAnalyzer.findEscapingVariables(program);
|
||||||
boolean[] used = new boolean[escaping.length];
|
boolean[] used = new boolean[escaping.length];
|
||||||
|
|
||||||
int[] stack = new int[graph.size() * 2];
|
int[] stack = new int[graph.size() * 2];
|
||||||
|
@ -54,7 +54,6 @@ public class UnusedVariableElimination implements MethodOptimization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Program program = method.getProgram();
|
|
||||||
InstructionOptimizer insnOptimizer = new InstructionOptimizer(used);
|
InstructionOptimizer insnOptimizer = new InstructionOptimizer(used);
|
||||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||||
BasicBlock block = program.basicBlockAt(i);
|
BasicBlock block = program.basicBlockAt(i);
|
||||||
|
|
|
@ -103,16 +103,16 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
Runnable finalizer = null;
|
Runnable finalizer = null;
|
||||||
try {
|
try {
|
||||||
ClassLoader classLoader = prepareClassLoader();
|
final ClassLoader classLoader = prepareClassLoader();
|
||||||
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'");
|
||||||
findTestClasses(classLoader, testFiles, "");
|
findTestClasses(classLoader, testFiles, "");
|
||||||
Log log = getLog();
|
final Log log = getLog();
|
||||||
new File(outputDir, "tests").mkdirs();
|
new File(outputDir, "tests").mkdirs();
|
||||||
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
resourceToFile("org/teavm/javascript/runtime.js", "runtime.js");
|
||||||
resourceToFile("org/teavm/maven/junit-support.js", "junit-support.js");
|
resourceToFile("org/teavm/maven/junit-support.js", "junit-support.js");
|
||||||
resourceToFile("org/teavm/maven/junit.css", "junit.css");
|
resourceToFile("org/teavm/maven/junit.css", "junit.css");
|
||||||
resourceToFile("org/teavm/maven/junit.html", "junit.html");
|
resourceToFile("org/teavm/maven/junit.html", "junit.html");
|
||||||
ClassHolderSource classSource = new ClasspathClassHolderSource(classLoader);
|
final ClassHolderSource classSource = new ClasspathClassHolderSource(classLoader);
|
||||||
for (String testClass : testClasses) {
|
for (String testClass : testClasses) {
|
||||||
ClassHolder classHolder = classSource.getClassHolder(testClass);
|
ClassHolder classHolder = classSource.getClassHolder(testClass);
|
||||||
if (classHolder == null) {
|
if (classHolder == null) {
|
||||||
|
@ -169,12 +169,22 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
};
|
};
|
||||||
executor = threadedExecutor;
|
executor = threadedExecutor;
|
||||||
}
|
}
|
||||||
for (MethodReference method : testMethods) {
|
for (final MethodReference method : testMethods) {
|
||||||
log.debug("Building test for " + method);
|
executor.execute(new Runnable() {
|
||||||
decompileClassesForTest(classLoader, method, fileNames.get(method), executor);
|
@Override public void run() {
|
||||||
|
log.debug("Building test for " + method);
|
||||||
|
try {
|
||||||
|
decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource), method,
|
||||||
|
fileNames.get(method), new SimpleFiniteExecutor());
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error generating JavaScript", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
++methodsGenerated;
|
++methodsGenerated;
|
||||||
}
|
}
|
||||||
log.info("Test files successfully generated for " + methodsGenerated + " method(s)");
|
executor.complete();
|
||||||
|
log.info("Test files successfully generated for " + methodsGenerated + " method(s).");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new MojoFailureException("IO error occured generating JavaScript files", e);
|
throw new MojoFailureException("IO error occured generating JavaScript files", e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -216,11 +226,11 @@ public class BuildJavascriptJUnitMojo extends AbstractMojo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decompileClassesForTest(ClassLoader classLoader, MethodReference methodRef, String targetName,
|
private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource,
|
||||||
FiniteExecutor executor) throws IOException {
|
MethodReference methodRef, String targetName, FiniteExecutor executor) throws IOException {
|
||||||
JavascriptBuilderFactory builderFactory = new JavascriptBuilderFactory();
|
JavascriptBuilderFactory builderFactory = new JavascriptBuilderFactory();
|
||||||
builderFactory.setClassLoader(classLoader);
|
builderFactory.setClassLoader(classLoader);
|
||||||
builderFactory.setClassSource(new ClasspathClassHolderSource(classLoader));
|
builderFactory.setClassSource(classSource);
|
||||||
builderFactory.setExecutor(executor);
|
builderFactory.setExecutor(executor);
|
||||||
JavascriptBuilder builder = builderFactory.create();
|
JavascriptBuilder builder = builderFactory.create();
|
||||||
builder.setMinifying(minifying);
|
builder.setMinifying(minifying);
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
<minifying>false</minifying>
|
<minifying>false</minifying>
|
||||||
<mainClass>org.teavm.samples.HelloWorld</mainClass>
|
<mainClass>org.teavm.samples.HelloWorld</mainClass>
|
||||||
<mainPageIncluded>true</mainPageIncluded>
|
<mainPageIncluded>true</mainPageIncluded>
|
||||||
<bytecodeLogging>true</bytecodeLogging>
|
<bytecodeLogging>false</bytecodeLogging>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user