wasm gc: reduce number of generated virtual table entries, reduce size of a simple program

This commit is contained in:
Alexey Andreev 2024-08-23 21:09:55 +02:00
parent 3e19ca341e
commit 4a345610cf
6 changed files with 22 additions and 9 deletions

View File

@ -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

View File

@ -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);

View File

@ -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<MethodReference> methodsAtCallSites;
Predicate<MethodReference> isVirtual;
private Map<String, Set<MethodDescriptor>> groupedMethodsAtCallSites = new HashMap<>();
private List<Table> tables = new ArrayList<>();
private Map<String, Table> 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());

View File

@ -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<String, WasmGCVirtualTable> virtualTables;
public WasmGCVirtualTableProvider(ListableClassReaderSource classes,
Collection<MethodReference> methodsAtCallSites) {
Collection<MethodReference> methodsAtCallSites, Predicate<MethodReference> isVirtual) {
var builder = new WasmGCVirtualTableBuilder();
builder.classes = classes;
builder.methodsAtCallSites = methodsAtCallSites;
builder.isVirtual = isVirtual;
builder.build();
virtualTables = builder.result;
}

View File

@ -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<MethodReference> 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<MethodReference> isVirtual) {
return new WasmGCVirtualTableProvider(classes, VirtualTableBuilder.getMethodsUsedOnCallSites(classes, true),
isVirtual);
}
public WasmFunction dummyInitializer() {

View File

@ -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);