Improve class initializer elimination

This commit is contained in:
Alexey Andreev 2023-11-07 18:46:01 +01:00
parent eca3dc61f5
commit 0ee994e913
6 changed files with 22 additions and 9 deletions

View File

@ -461,7 +461,8 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
int start = sourceWriter.getOffset();
RuntimeRenderer runtimeRenderer = new RuntimeRenderer(classes, sourceWriter);
RuntimeRenderer runtimeRenderer = new RuntimeRenderer(classes, sourceWriter,
controller.getClassInitializerInfo());
runtimeRenderer.prepareAstParts(renderer.isThreadLibraryUsed());
declarations.replay(runtimeRenderer.sink, RememberedSource.FILTER_REF);
epilogue.replay(runtimeRenderer.sink, RememberedSource.FILTER_REF);

View File

@ -33,6 +33,7 @@ import org.teavm.backend.javascript.templating.RemovablePartsFinder;
import org.teavm.backend.javascript.templating.TemplatingAstTransformer;
import org.teavm.backend.javascript.templating.TemplatingAstWriter;
import org.teavm.model.ClassReaderSource;
import org.teavm.model.analysis.ClassInitializerInfo;
import org.teavm.vm.RenderingException;
public class RuntimeRenderer {
@ -41,10 +42,13 @@ public class RuntimeRenderer {
private final RemovablePartsFinder removablePartsFinder = new RemovablePartsFinder();
private final ClassReaderSource classSource;
private final SourceWriter writer;
private final ClassInitializerInfo classInitializerInfo;
public RuntimeRenderer(ClassReaderSource classSource, SourceWriter writer) {
public RuntimeRenderer(ClassReaderSource classSource, SourceWriter writer,
ClassInitializerInfo classInitializerInfo) {
this.classSource = classSource;
this.writer = writer;
this.classInitializerInfo = classInitializerInfo;
}
public void prepareAstParts(boolean threadLibraryUsed) {
@ -76,7 +80,7 @@ public class RuntimeRenderer {
}
private void renderHandWrittenRuntime(AstRoot ast) {
var astWriter = new TemplatingAstWriter(writer, null, null);
var astWriter = new TemplatingAstWriter(writer, null, null, classInitializerInfo);
astWriter.hoist(ast);
astWriter.print(ast);
}

View File

@ -75,7 +75,7 @@ public class JavaScriptTemplate {
var thisFragment = parameters.apply(0);
var body = node.getBody();
return (writer, precedence) -> {
var astWriter = new TemplatingAstWriter(writer, nameParameters, node);
var astWriter = new TemplatingAstWriter(writer, nameParameters, node, null);
for (var entry : fragments.entrySet()) {
astWriter.setFragment(entry.getKey(), entry.getValue());
}

View File

@ -19,7 +19,6 @@ import org.mozilla.javascript.ast.AstNode;
import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.Block;
import org.mozilla.javascript.ast.FunctionNode;
import org.mozilla.javascript.ast.IfStatement;
import org.mozilla.javascript.ast.Scope;
import org.mozilla.javascript.ast.VariableDeclaration;
import org.teavm.backend.javascript.ast.AstVisitor;
@ -51,7 +50,7 @@ public class LetJoiner extends AstVisitor {
private void visitMany(AstNode node) {
VariableDeclaration previous = null;
for (var childNode = node.getFirstChild(); childNode != null; ) {
for (var childNode = node.getFirstChild(); childNode != null;) {
var nextNode = childNode.getNext();
var child = (AstNode) childNode;
if (child instanceof VariableDeclaration) {

View File

@ -30,14 +30,18 @@ import org.teavm.backend.javascript.rendering.DefaultGlobalNameWriter;
import org.teavm.model.FieldReference;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
import org.teavm.model.analysis.ClassInitializerInfo;
public class TemplatingAstWriter extends AstWriter {
private Map<String, SourceFragment> names;
private Scope scope;
private Map<String, SourceFragment> fragments = new HashMap<>();
private ClassInitializerInfo classInitializerInfo;
public TemplatingAstWriter(SourceWriter writer, Map<String, SourceFragment> names, Scope scope) {
public TemplatingAstWriter(SourceWriter writer, Map<String, SourceFragment> names, Scope scope,
ClassInitializerInfo classInitializerInfo) {
super(writer, new DefaultGlobalNameWriter(writer));
this.classInitializerInfo = classInitializerInfo;
this.names = names;
this.scope = scope;
if (names != null) {
@ -132,7 +136,12 @@ public class TemplatingAstWriter extends AstWriter {
if (!(classArg instanceof StringLiteral)) {
return false;
}
writer.appendClassInit(((StringLiteral) classArg).getValue());
var className = ((StringLiteral) classArg).getValue();
if (classInitializerInfo == null || classInitializerInfo.isDynamicInitializer(className)) {
writer.appendClassInit(className);
} else {
writer.append("(()").ws().append("=>").ws().append("{})");
}
return true;
}

View File

@ -279,7 +279,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
}
void analyzeInitializer(String className) {
if (className.equals(currentClass)) {
if (className.equals(currentClass) || className.equals(methodInfo.method.getClassName())) {
return;
}