From 4a345610cf8e62c035a57a56d1648003f2dd133e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 23 Aug 2024 21:09:55 +0200 Subject: [PATCH] wasm gc: reduce number of generated virtual table entries, reduce size of a simple program --- .../classlib/impl/console/JsConsolePrintStream.java | 4 ++-- .../java/org/teavm/backend/wasm/WasmGCTarget.java | 3 ++- .../wasm/gc/vtable/WasmGCVirtualTableBuilder.java | 5 +++++ .../wasm/gc/vtable/WasmGCVirtualTableProvider.java | 4 +++- .../generate/gc/WasmGCDeclarationsGenerator.java | 13 +++++++++---- .../generate/gc/classes/WasmGCClassGenerator.java | 2 +- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/impl/console/JsConsolePrintStream.java b/classlib/src/main/java/org/teavm/classlib/impl/console/JsConsolePrintStream.java index 953cc161e..f80fc479e 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/console/JsConsolePrintStream.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/console/JsConsolePrintStream.java @@ -15,10 +15,10 @@ */ package org.teavm.classlib.impl.console; -import java.io.OutputStream; import java.io.PrintStream; import java.nio.ByteBuffer; import java.nio.CharBuffer; +import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; @@ -30,7 +30,7 @@ public abstract class JsConsolePrintStream extends PrintStream { private Runnable flushAction; public JsConsolePrintStream() { - super((OutputStream) null); + super(null, false, (Charset) null); } @Override diff --git a/core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java b/core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java index cf00546f4..87bbb1ae4 100644 --- a/core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java +++ b/core/src/main/java/org/teavm/backend/wasm/WasmGCTarget.java @@ -122,7 +122,8 @@ public class WasmGCTarget implements TeaVMTarget { controller.getDependencyInfo(), controller.getDiagnostics(), customGenerators, - intrinsics + intrinsics, + controller::isVirtual ); declarationsGenerator.setFriendlyToDebugger(controller.isFriendlyToDebugger()); var moduleGenerator = new WasmGCModuleGenerator(declarationsGenerator); diff --git a/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableBuilder.java b/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableBuilder.java index d644e6360..0c2bbdc34 100644 --- a/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableBuilder.java +++ b/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableBuilder.java @@ -24,6 +24,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; import org.teavm.common.LCATree; import org.teavm.model.ClassReader; @@ -35,6 +36,7 @@ import org.teavm.model.MethodReference; class WasmGCVirtualTableBuilder { ListableClassReaderSource classes; Collection methodsAtCallSites; + Predicate isVirtual; private Map> groupedMethodsAtCallSites = new HashMap<>(); private List tables = new ArrayList<>(); private Map tableMap = new HashMap<>(); @@ -178,6 +180,9 @@ class WasmGCVirtualTableBuilder { if (method.getProgram() == null && !method.hasModifier(ElementModifier.NATIVE)) { continue; } + if (!isVirtual.test(method.getReference())) { + continue; + } var index = indexes.getOrDefault(method.getDescriptor(), -1); if (index >= 0) { table.implementors.set(index, method.getReference()); diff --git a/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableProvider.java b/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableProvider.java index 70f9ba394..3d78965b7 100644 --- a/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableProvider.java +++ b/core/src/main/java/org/teavm/backend/wasm/gc/vtable/WasmGCVirtualTableProvider.java @@ -17,6 +17,7 @@ package org.teavm.backend.wasm.gc.vtable; import java.util.Collection; import java.util.Map; +import java.util.function.Predicate; import org.teavm.model.ListableClassReaderSource; import org.teavm.model.MethodReference; @@ -24,10 +25,11 @@ public class WasmGCVirtualTableProvider { private Map virtualTables; public WasmGCVirtualTableProvider(ListableClassReaderSource classes, - Collection methodsAtCallSites) { + Collection methodsAtCallSites, Predicate isVirtual) { var builder = new WasmGCVirtualTableBuilder(); builder.classes = classes; builder.methodsAtCallSites = methodsAtCallSites; + builder.isVirtual = isVirtual; builder.build(); virtualTables = builder.result; } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/WasmGCDeclarationsGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/WasmGCDeclarationsGenerator.java index 70487cc92..5a7c57bc6 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/WasmGCDeclarationsGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/WasmGCDeclarationsGenerator.java @@ -16,6 +16,7 @@ package org.teavm.backend.wasm.generate.gc; import java.util.List; +import java.util.function.Predicate; import org.teavm.backend.wasm.BaseWasmFunctionRepository; import org.teavm.backend.wasm.WasmFunctionTypes; import org.teavm.backend.wasm.gc.vtable.WasmGCVirtualTableProvider; @@ -33,6 +34,7 @@ import org.teavm.dependency.DependencyInfo; import org.teavm.diagnostics.Diagnostics; import org.teavm.model.ClassHierarchy; import org.teavm.model.ListableClassHolderSource; +import org.teavm.model.MethodReference; import org.teavm.model.analysis.ClassInitializerInfo; import org.teavm.model.analysis.ClassMetadataRequirements; import org.teavm.model.classes.TagRegistry; @@ -52,11 +54,12 @@ public class WasmGCDeclarationsGenerator { DependencyInfo dependencyInfo, Diagnostics diagnostics, WasmGCCustomGeneratorProvider customGenerators, - WasmGCIntrinsicProvider intrinsics + WasmGCIntrinsicProvider intrinsics, + Predicate isVirtual ) { this.module = module; hierarchy = new ClassHierarchy(classes); - var virtualTables = createVirtualTableProvider(classes); + var virtualTables = createVirtualTableProvider(classes, isVirtual); functionTypes = new WasmFunctionTypes(module); var names = new WasmNameProvider(); methodGenerator = new WasmGCMethodGenerator( @@ -130,8 +133,10 @@ public class WasmGCDeclarationsGenerator { } } - private static WasmGCVirtualTableProvider createVirtualTableProvider(ListableClassHolderSource classes) { - return new WasmGCVirtualTableProvider(classes, VirtualTableBuilder.getMethodsUsedOnCallSites(classes, true)); + private static WasmGCVirtualTableProvider createVirtualTableProvider(ListableClassHolderSource classes, + Predicate isVirtual) { + return new WasmGCVirtualTableProvider(classes, VirtualTableBuilder.getMethodsUsedOnCallSites(classes, true), + isVirtual); } public WasmFunction dummyInitializer() { diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java index 466c8474c..98a14150f 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java @@ -451,7 +451,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit .getUnpackedType(); var expectedFunctionType = (WasmFunctionType) expectedType.composite; var function = functionProvider.forInstanceMethod(implementor); - if (entry.getOrigin().getClassName().equals(implementor.getClassName()) + if (!entry.getOrigin().getClassName().equals(implementor.getClassName()) || expectedFunctionType != function.getType()) { var wrapperFunction = new WasmFunction(expectedFunctionType); module.functions.add(wrapperFunction);