diff --git a/teavm-core/src/main/java/org/teavm/common/CommutatedWriter.java b/teavm-core/src/main/java/org/teavm/common/CommutatedWriter.java new file mode 100644 index 000000000..adcc208f8 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/common/CommutatedWriter.java @@ -0,0 +1,93 @@ +/* + * 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.common; + +import java.io.IOException; +import java.io.Writer; + +/** + * + * @author Alexey Andreev + */ +public class CommutatedWriter extends Writer { + private ThreadLocal buffer = new ThreadLocal<>(); + private Writer innerWriter; + + public CommutatedWriter(Writer innerWriter) { + this.innerWriter = innerWriter; + } + + private StringBuilder getBuffer() { + if (buffer.get() == null) { + buffer.set(new StringBuilder()); + } + return buffer.get(); + } + + @Override + public void write(int c) throws IOException { + getBuffer().append(c); + } + + @Override + public void write(char[] cbuf) throws IOException { + getBuffer().append(cbuf); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + getBuffer().append(cbuf, off, len); + } + + @Override + public void write(String str) throws IOException { + getBuffer().append(str); + } + + @Override + public void write(String str, int off, int len) throws IOException { + getBuffer().append(str, off, len + off); + } + + @Override + public Writer append(CharSequence csq) throws IOException { + getBuffer().append(csq); + return this; + } + + @Override + public Writer append(CharSequence csq, int start, int end) throws IOException { + getBuffer().append(csq, start, end); + return this; + } + + @Override + public Writer append(char c) throws IOException { + getBuffer().append(c); + return this; + } + + @Override + public void flush() throws IOException { + } + + @Override + public void close() throws IOException { + StringBuilder sb = getBuffer(); + innerWriter.write(sb.toString()); + buffer.set(null); + } +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java index ccbe610ac..f033ab6e3 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/JavascriptBuilder.java @@ -104,9 +104,11 @@ public class JavascriptBuilder { executor.complete(); ListableClassHolderSource classSet = dependencyChecker.cutUnachievableClasses(); Decompiler decompiler = new Decompiler(classSet, classLoader); - ClassSetOptimizer optimizer = new ClassSetOptimizer(); + ClassSetOptimizer optimizer = new ClassSetOptimizer(executor); optimizer.optimizeAll(classSet); + executor.complete(); allocateRegisters(classSet); + executor.complete(); if (bytecodeLogging) { try { logBytecode(new PrintWriter(new OutputStreamWriter(logStream, "UTF-8")), classSet); @@ -134,12 +136,16 @@ public class JavascriptBuilder { } private void allocateRegisters(ListableClassHolderSource classes) { - RegisterAllocator allocator = new RegisterAllocator(); for (String className : classes.getClassNames()) { ClassHolder cls = classes.getClassHolder(className); - for (MethodHolder method : cls.getMethods()) { + for (final MethodHolder method : cls.getMethods()) { if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) { - allocator.allocateRegisters(method); + executor.execute(new Runnable() { + @Override public void run() { + RegisterAllocator allocator = new RegisterAllocator(); + allocator.allocateRegisters(method); + } + }); } } } diff --git a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java index e1b3999b4..8c30e4ca0 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java +++ b/teavm-core/src/main/java/org/teavm/optimization/ClassSetOptimizer.java @@ -17,6 +17,7 @@ package org.teavm.optimization; import java.util.Arrays; import java.util.List; +import java.util.concurrent.Executor; import org.teavm.model.ClassHolder; import org.teavm.model.ListableClassHolderSource; import org.teavm.model.MethodHolder; @@ -28,15 +29,26 @@ import org.teavm.model.MethodHolder; public class ClassSetOptimizer { private List optimizations = Arrays.asList( new CommonSubexpressionElimination(), new UnusedVariableElimination()); + private Executor executor; + + public ClassSetOptimizer(Executor executor) { + super(); + this.executor = executor; + } public void optimizeAll(ListableClassHolderSource classSource) { for (String className : classSource.getClassNames()) { ClassHolder cls = classSource.getClassHolder(className); - for (MethodHolder method : cls.getMethods()) { + for (final MethodHolder method : cls.getMethods()) { if (method.getProgram() != null && method.getProgram().basicBlockCount() > 0) { - for (MethodOptimization optimization : optimizations) { - optimization.optimize(method); - } + executor.execute(new Runnable() { + @Override + public void run() { + for (MethodOptimization optimization : optimizations) { + optimization.optimize(method); + } + } + }); } } }