From eba560d37380f97016423b3800ed0c0774fc3a0e Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 26 Feb 2015 21:30:04 +0300 Subject: [PATCH] Don't generate monitorenter/monitorexit where unnecessary --- .../dependency/DependencyGraphBuilder.java | 6 +- .../java/org/teavm/javascript/Renderer.java | 68 ++++--- .../javascript/spi/GeneratorContext.java | 2 + .../teavm/model/util/AsyncMethodFinder.java | 174 ------------------ .../platform/plugin/PlatformGenerator.java | 16 +- 5 files changed, 57 insertions(+), 209 deletions(-) diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index 39aa16b9d..82f3a23a5 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -496,8 +496,7 @@ class DependencyGraphBuilder { @Override public void monitorEnter(VariableReader objectRef) { MethodDependency methodDep = dependencyChecker.linkMethod( - new MethodReference(Object.class, "monitorEnter", Object.class, void.class), - new CallLocation(caller.getMethod(), currentLocation)); + new MethodReference(Object.class, "monitorEnter", Object.class, void.class), null); nodes[objectRef.getIndex()].connect(methodDep.getVariable(1)); methodDep.use(); } @@ -505,8 +504,7 @@ class DependencyGraphBuilder { @Override public void monitorExit(VariableReader objectRef) { MethodDependency methodDep = dependencyChecker.linkMethod( - new MethodReference(Object.class, "monitorExit", Object.class, void.class), - new CallLocation(caller.getMethod(), currentLocation)); + new MethodReference(Object.class, "monitorExit", Object.class, void.class), null); nodes[objectRef.getIndex()].connect(methodDep.getVariable(1)); methodDep.use(); } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 0c47fd733..18d8848a9 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -71,34 +71,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext boolean wasGrouped; } - @Override - public void visit(MonitorEnterStatement statement) { - try { - MethodReference monitorEnterRef = new MethodReference( - Object.class, "monitorEnter", Object.class, void.class); - writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("("); - statement.getObjectRef().acceptVisitor(this); - writer.append(",").ws(); - writer.append("$rt_continue($part_").append(statement.getAsyncTarget()).append(')'); - writer.append(");").softNewLine(); - } catch (IOException ex){ - throw new RenderingException("IO error occured", ex); - } - } - - @Override - public void visit(MonitorExitStatement statement) { - try { - MethodReference monitorExitRef = new MethodReference( - Object.class, "monitorExit", Object.class, void.class); - writer.appendMethodBody(monitorExitRef).append("("); - statement.getObjectRef().acceptVisitor(this); - writer.append(");").softNewLine(); - } catch (IOException ex){ - throw new RenderingException("IO error occured", ex); - } - } - private static class InjectorHolder { public final Injector injector; @@ -798,6 +770,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext return asyncMethods.contains(method); } + @Override + public boolean isAsyncFamily(MethodReference method) { + return asyncFamilyMethods.contains(method); + } + @Override public String getCompleteContinuation() { return "$return"; @@ -2007,6 +1984,41 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } + @Override + public void visit(MonitorEnterStatement statement) { + if (!async) { + return; + } + try { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorEnter", Object.class, void.class); + writer.append("return ").append(naming.getFullNameForAsync(monitorEnterRef)).append("("); + statement.getObjectRef().acceptVisitor(this); + writer.append(",").ws(); + writer.append("$rt_continue($part_").append(statement.getAsyncTarget()).append(')'); + writer.append(");").softNewLine(); + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); + } + } + + @Override + public void visit(MonitorExitStatement statement) { + if (!async) { + return; + } + try { + MethodReference monitorExitRef = new MethodReference( + Object.class, "monitorExit", Object.class, void.class); + writer.appendMethodBody(monitorExitRef).append("("); + statement.getObjectRef().acceptVisitor(this); + writer.append(");").softNewLine(); + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); + } + } + + private Injector getInjector(MethodReference ref) { InjectorHolder holder = injectorMap.get(ref); if (holder == null) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java index 927813f0f..821d42c45 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java +++ b/teavm-core/src/main/java/org/teavm/javascript/spi/GeneratorContext.java @@ -40,5 +40,7 @@ public interface GeneratorContext extends ServiceRepository { boolean isAsync(MethodReference method); + boolean isAsyncFamily(MethodReference method); + Diagnostics getDiagnostics(); } diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java index 2fc095329..a52672b29 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncMethodFinder.java @@ -24,7 +24,6 @@ import org.teavm.javascript.spi.Async; import org.teavm.javascript.spi.InjectedBy; import org.teavm.javascript.spi.Sync; import org.teavm.model.*; -import org.teavm.model.instructions.*; /** * @@ -62,17 +61,6 @@ public class AsyncMethodFinder { } if (method.getAnnotations().get(Async.class.getName()) != null) { add(method.getReference()); - } else if (method.getProgram() != null) { - ProgramReader program = method.getProgram(); - AsyncInstructionFinder insnFinder = new AsyncInstructionFinder(); - for (int i = 0; i < program.basicBlockCount(); ++i) { - BasicBlockReader block = program.basicBlockAt(i); - block.readAllInstructions(insnFinder); - if (insnFinder.hasAsync) { - add(method.getReference()); - break; - } - } } } } @@ -197,166 +185,4 @@ public class AsyncMethodFinder { } } } - - private class AsyncInstructionFinder implements InstructionReader { - boolean hasAsync; - - @Override - public void location(InstructionLocation location) { - } - - @Override - public void nop() { - } - - @Override - public void classConstant(VariableReader receiver, ValueType cst) { - } - - @Override - public void nullConstant(VariableReader receiver) { - } - - @Override - public void integerConstant(VariableReader receiver, int cst) { - } - - @Override - public void longConstant(VariableReader receiver, long cst) { - } - - @Override - public void floatConstant(VariableReader receiver, float cst) { - } - - @Override - public void doubleConstant(VariableReader receiver, double cst) { - } - - @Override - public void stringConstant(VariableReader receiver, String cst) { - } - - @Override - public void binary(BinaryOperation op, VariableReader receiver, VariableReader first, VariableReader second, - NumericOperandType type) { - } - - @Override - public void negate(VariableReader receiver, VariableReader operand, NumericOperandType type) { - } - - @Override - public void assign(VariableReader receiver, VariableReader assignee) { - } - - @Override - public void cast(VariableReader receiver, VariableReader value, ValueType targetType) { - } - - @Override - public void cast(VariableReader receiver, VariableReader value, NumericOperandType sourceType, - NumericOperandType targetType) { - } - - @Override - public void cast(VariableReader receiver, VariableReader value, IntegerSubtype type, - CastIntegerDirection targetType) { - } - - @Override - public void jumpIf(BranchingCondition cond, VariableReader operand, BasicBlockReader consequent, - BasicBlockReader alternative) { - } - - @Override - public void jumpIf(BinaryBranchingCondition cond, VariableReader first, VariableReader second, - BasicBlockReader consequent, BasicBlockReader alternative) { - } - - @Override - public void jump(BasicBlockReader target) { - } - - @Override - public void choose(VariableReader condition, List table, - BasicBlockReader defaultTarget) { - } - - @Override - public void exit(VariableReader valueToReturn) { - } - - @Override - public void raise(VariableReader exception) { - } - - @Override - public void createArray(VariableReader receiver, ValueType itemType, VariableReader size) { - } - - @Override - public void createArray(VariableReader receiver, ValueType itemType, - List dimensions) { - } - - @Override - public void create(VariableReader receiver, String type) { - } - - @Override - public void getField(VariableReader receiver, VariableReader instance, FieldReference field, - ValueType fieldType) { - } - - @Override - public void putField(VariableReader instance, FieldReference field, VariableReader value) { - } - - @Override - public void arrayLength(VariableReader receiver, VariableReader array) { - } - - @Override - public void cloneArray(VariableReader receiver, VariableReader array) { - } - - @Override - public void unwrapArray(VariableReader receiver, VariableReader array, ArrayElementType elementType) { - } - - @Override - public void getElement(VariableReader receiver, VariableReader array, VariableReader index) { - } - - @Override - public void putElement(VariableReader array, VariableReader index, VariableReader value) { - } - - @Override - public void invoke(VariableReader receiver, VariableReader instance, MethodReference method, - List arguments, InvocationType type) { - } - - @Override - public void isInstance(VariableReader receiver, VariableReader value, ValueType type) { - } - - @Override - public void initClass(String className) { - } - - @Override - public void nullCheck(VariableReader receiver, VariableReader value) { - } - - @Override - public void monitorEnter(VariableReader objectRef) { - hasAsync = true; - } - - @Override - public void monitorExit(VariableReader objectRef) { - } - } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index 9e6fc50cc..1360b334a 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -184,11 +184,21 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin } private void generateSchedule(GeneratorContext context, SourceWriter writer, boolean timeout) throws IOException { + MethodReference launchRef = new MethodReference(Platform.class, "launchThread", + PlatformRunnable.class, void.class); String runnable = context.getParameterName(1); writer.append("return window.setTimeout(function()").ws().append("{").indent().softNewLine(); - String methodName = writer.getNaming().getFullNameFor(new MethodReference(Platform.class, "launchThread", - PlatformRunnable.class, void.class)); - writer.append("$rt_rootInvocationAdapter(").append(methodName).append(")(").append(runnable).append(");") + boolean async = context.isAsyncFamily(launchRef); + String methodName = async ? writer.getNaming().getFullNameForAsync(launchRef) : + writer.getNaming().getFullNameFor(launchRef); + if (async) { + writer.append("$rt_rootInvocationAdapter("); + } + writer.append(methodName); + if (async) { + writer.append(")"); + } + writer.append("(").append(runnable).append(");") .softNewLine(); writer.outdent().append("},").ws().append(timeout ? context.getParameterName(2) : "0") .append(");").softNewLine();