diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/js/JSStructuredControlflowCodeGenerator.java b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/js/JSStructuredControlflowCodeGenerator.java index 82c8fed9e0..6d9d65d101 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/js/JSStructuredControlflowCodeGenerator.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/js/JSStructuredControlflowCodeGenerator.java @@ -39,6 +39,7 @@ import de.mirkosertic.bytecoder.core.ir.FieldReference; import de.mirkosertic.bytecoder.core.ir.FrameDebugInfo; import de.mirkosertic.bytecoder.core.ir.Goto; +import de.mirkosertic.bytecoder.core.ir.Graph; import de.mirkosertic.bytecoder.core.ir.If; import de.mirkosertic.bytecoder.core.ir.InstanceOf; import de.mirkosertic.bytecoder.core.ir.InvokeDynamicExpression; @@ -99,6 +100,7 @@ import java.lang.invoke.LambdaMetafactory; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -133,7 +135,14 @@ public JSStructuredControlflowCodeGenerator(final CompileUnit compileUnit, final } @Override - public void registerVariables(final List variables) { + public void registerVariables(final Graph g) { + + if (g.nodes().stream().anyMatch(t -> t.nodeType == NodeType.This)) { + writeIndent(); + pw.println("var th = this;"); + } + + final List variables = g.nodes().stream().filter(t -> t instanceof AbstractVar).map(t -> (AbstractVar) t).collect(Collectors.toList()); for (int i = 0; i < variables.size(); i++) { final AbstractVar v = variables.get(i); final String varName; @@ -648,9 +657,7 @@ private void generateInvokeDynamicLambdaMetaFactoryInvocation(final InvokeDynami final ResolvedMethod implementationMethod = argImplMethod.resolvedMethod; final List allArgs = new ArrayList<>(); - for (int i = 1; i < node.incomingDataFlows.length; i++) { - allArgs.add(node.incomingDataFlows[i]); - } + allArgs.addAll(Arrays.asList(node.incomingDataFlows).subList(1, node.incomingDataFlows.length)); for (int i = 0; i < argInstanceMethodType.type.getArgumentTypes().length; i++) { allArgs.add(new LinkageArgument("linkarg" + i, argInstanceMethodType.type.getArgumentTypes()[i])); @@ -1999,7 +2006,7 @@ private void writeExpression(final TypeReference node) { } private void writeExpression(final This node) { - pw.print("this"); + pw.print("th"); } private void writeExpression(final New node) { diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/opencl/OpenCLStructuredControlflowCodeGenerator.java b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/opencl/OpenCLStructuredControlflowCodeGenerator.java index ba8360aef5..feaa8940de 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/opencl/OpenCLStructuredControlflowCodeGenerator.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/opencl/OpenCLStructuredControlflowCodeGenerator.java @@ -31,6 +31,7 @@ import de.mirkosertic.bytecoder.core.ir.Div; import de.mirkosertic.bytecoder.core.ir.FrameDebugInfo; import de.mirkosertic.bytecoder.core.ir.Goto; +import de.mirkosertic.bytecoder.core.ir.Graph; import de.mirkosertic.bytecoder.core.ir.If; import de.mirkosertic.bytecoder.core.ir.LineNumberDebugInfo; import de.mirkosertic.bytecoder.core.ir.LookupSwitch; @@ -78,6 +79,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class OpenCLStructuredControlflowCodeGenerator implements StructuredControlflowCodeGenerator { @@ -102,7 +104,8 @@ public OpenCLStructuredControlflowCodeGenerator(final CompileUnit compileUnit, f } @Override - public void registerVariables(final List variables) { + public void registerVariables(final Graph g) { + final List variables = g.nodes().stream().filter(t -> t instanceof AbstractVar).map(t -> (AbstractVar) t).collect(Collectors.toList()); for (int i = 0; i < variables.size(); i++) { final AbstractVar v = variables.get(i); final String varName; diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/Sequencer.java b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/Sequencer.java index bee89c3be7..2391adc593 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/Sequencer.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/Sequencer.java @@ -15,7 +15,6 @@ */ package de.mirkosertic.bytecoder.core.backend.sequencer; -import de.mirkosertic.bytecoder.core.ir.AbstractVar; import de.mirkosertic.bytecoder.core.ir.ArrayStore; import de.mirkosertic.bytecoder.core.ir.ClassInitialization; import de.mirkosertic.bytecoder.core.ir.ControlTokenConsumer; @@ -82,8 +81,7 @@ public Sequencer(final Graph g, final DominatorTree dominatorTree, final Structu this.codegenerator = codegenerator; final ControlTokenConsumer startNode = g.regionByLabel(Graph.START_REGION_NAME); - final List variables = g.nodes().stream().filter(t -> t instanceof AbstractVar).map(t -> (AbstractVar) t).collect(Collectors.toList()); - codegenerator.registerVariables(variables); + codegenerator.registerVariables(g); visitDominationTreeOf(startNode, new Stack<>()); } diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/StructuredControlflowCodeGenerator.java b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/StructuredControlflowCodeGenerator.java index b358b88bae..ab222e02db 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/StructuredControlflowCodeGenerator.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/sequencer/StructuredControlflowCodeGenerator.java @@ -15,12 +15,12 @@ */ package de.mirkosertic.bytecoder.core.backend.sequencer; -import de.mirkosertic.bytecoder.core.ir.AbstractVar; import de.mirkosertic.bytecoder.core.ir.ArrayStore; import de.mirkosertic.bytecoder.core.ir.ClassInitialization; import de.mirkosertic.bytecoder.core.ir.Copy; import de.mirkosertic.bytecoder.core.ir.FrameDebugInfo; import de.mirkosertic.bytecoder.core.ir.Goto; +import de.mirkosertic.bytecoder.core.ir.Graph; import de.mirkosertic.bytecoder.core.ir.If; import de.mirkosertic.bytecoder.core.ir.LineNumberDebugInfo; import de.mirkosertic.bytecoder.core.ir.LookupSwitch; @@ -35,11 +35,9 @@ import de.mirkosertic.bytecoder.core.ir.Unwind; import org.objectweb.asm.Type; -import java.util.List; - public interface StructuredControlflowCodeGenerator { - void registerVariables(List variables); + void registerVariables(Graph g); void write(MethodInvocation node); diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/wasm/WasmStructuredControlflowCodeGenerator.java b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/wasm/WasmStructuredControlflowCodeGenerator.java index 502c29b05a..ba0f53b01a 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/backend/wasm/WasmStructuredControlflowCodeGenerator.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/backend/wasm/WasmStructuredControlflowCodeGenerator.java @@ -135,6 +135,7 @@ import java.util.Map; import java.util.Set; import java.util.function.Function; +import java.util.stream.Collectors; public class WasmStructuredControlflowCodeGenerator implements StructuredControlflowCodeGenerator { @@ -273,7 +274,9 @@ public WasmStructuredControlflowCodeGenerator(final CompileUnit compileUnit, fin } @Override - public void registerVariables(final List variables) { + public void registerVariables(final Graph g) { + + final List variables = g.nodes().stream().filter(t -> t instanceof AbstractVar).map(t -> (AbstractVar) t).collect(Collectors.toList()); for (int i = 0; i < variables.size(); i++) { final AbstractVar v = variables.get(i); diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/ir/This.java b/core/src/main/java/de/mirkosertic/bytecoder/core/ir/This.java index c7b203496b..ab490b6118 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/ir/This.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/ir/This.java @@ -28,8 +28,14 @@ public String additionalDebugInfo() { return ": " + type; } + @Override + public boolean isConstant() { + return true; + } + @Override public This stampInto(final Graph target) { return target.newThis(type); } + } diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/PHIorVariableIsConstant.java b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/PHIorVariableIsConstant.java index 63d8ce2d81..631371b72b 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/PHIorVariableIsConstant.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/PHIorVariableIsConstant.java @@ -56,7 +56,7 @@ public boolean optimize(final BackendType backendType, final CompileUnit compile final Node source = workingItem.incomingDataFlows[0]; // And only one outgoing dataflow // At this point we are sure it is a variable or phi - final Node target = g.outgoingDataFlowsFor(workingItem)[0]; + final Node target = outgoingDataFlows[0]; g.remapDataFlow(target, source); diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/STATS.md b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/STATS.md index 77224b42c7..3d09ef76a0 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/STATS.md +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/STATS.md @@ -64,3 +64,8 @@ JBox2D JS Opt1 2026648 bytes LUA Wasm Opt1 613036 bytes LUA JS Opt1 2220653 bytes + + JBox2D Wasm Opt2 568419 bytes + JBox2D JS Opt2 1956788 bytes + LUA Wasm Opt2 597855 bytes + LUA JS Opt2 2172070 bytes diff --git a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/VariableIsVariable.java b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/VariableIsVariable.java index 8e38984a80..2b1746e092 100644 --- a/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/VariableIsVariable.java +++ b/core/src/main/java/de/mirkosertic/bytecoder/core/optimizer/VariableIsVariable.java @@ -56,7 +56,7 @@ public boolean optimize(final BackendType backendType, final CompileUnit compile final Node source = workingItem.incomingDataFlows[0]; // And only one outgoing dataflow // At this point we are sure it is a variable or phi - final Node target = g.outgoingDataFlowsFor(workingItem)[0]; + final Node target = outgoingDataFlows[0]; g.remapDataFlow(target, source);