mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
wasm gc: group structurally equal different substructures into recursive group in order to benefit from using native ref.test
/rest.cast
instructions for classes
This commit is contained in:
parent
55ac5d0321
commit
944fd22513
@ -300,6 +300,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||
var structName = names.topLevel(names.suggestForType(type));
|
||||
classInfo.structure = new WasmStructure(structName,
|
||||
fields -> fillFields(finalClassInfo, fields, type));
|
||||
classInfo.structure.setNominal(true);
|
||||
module.types.add(classInfo.structure);
|
||||
nonInitializedStructures.add(classInfo.structure);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ import org.teavm.backend.wasm.model.expression.WasmTest;
|
||||
import org.teavm.backend.wasm.model.expression.WasmThrow;
|
||||
import org.teavm.backend.wasm.model.expression.WasmUnreachable;
|
||||
import org.teavm.model.ClassHierarchy;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.FieldReference;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.TextLocation;
|
||||
@ -517,7 +518,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||
}
|
||||
|
||||
private boolean canCastNatively(ValueType type) {
|
||||
/*if (type instanceof ValueType.Array) {
|
||||
if (type instanceof ValueType.Array) {
|
||||
return true;
|
||||
}
|
||||
var className = ((ValueType.Object) type).getClassName();
|
||||
@ -525,8 +526,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||
if (cls == null) {
|
||||
return false;
|
||||
}
|
||||
return !cls.hasModifier(ElementModifier.INTERFACE);*/
|
||||
return false;
|
||||
return !cls.hasModifier(ElementModifier.INTERFACE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,6 +25,7 @@ public class WasmStructure extends WasmCompositeType {
|
||||
private List<WasmField> fieldsStorage = new ArrayList<>();
|
||||
private WasmStructure supertype;
|
||||
private boolean indexesValid = true;
|
||||
private boolean nominal;
|
||||
|
||||
public WasmStructure(String name) {
|
||||
super(name);
|
||||
@ -57,6 +58,14 @@ public class WasmStructure extends WasmCompositeType {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isNominal() {
|
||||
return nominal;
|
||||
}
|
||||
|
||||
public void setNominal(boolean nominal) {
|
||||
this.nominal = nominal;
|
||||
}
|
||||
|
||||
void ensureIndexes() {
|
||||
if (!indexesValid) {
|
||||
indexesValid = true;
|
||||
|
@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.teavm.backend.wasm.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import org.teavm.common.Graph;
|
||||
import org.teavm.common.GraphBuilder;
|
||||
|
||||
@ -29,9 +32,63 @@ final class WasmTypeGraphBuilder {
|
||||
visitor.currentIndex = module.types.indexOf(type);
|
||||
type.acceptVisitor(visitor);
|
||||
}
|
||||
|
||||
addNominalStructures(module, types, graphBuilder);
|
||||
|
||||
return graphBuilder.build();
|
||||
}
|
||||
|
||||
private static void addNominalStructures(WasmModule module, Iterable<WasmCompositeType> types,
|
||||
GraphBuilder graphBuilder) {
|
||||
var subStructures = new HashMap<WasmStructure, List<WasmStructure>>();
|
||||
var topLevelStructures = new ArrayList<WasmStructure>();
|
||||
for (var type : types) {
|
||||
if (type instanceof WasmStructure) {
|
||||
var structure = (WasmStructure) type;
|
||||
if (structure.isNominal()) {
|
||||
if (structure.getSupertype() != null) {
|
||||
subStructures.computeIfAbsent(structure.getSupertype(), k -> new ArrayList<>()).add(structure);
|
||||
} else {
|
||||
topLevelStructures.add(structure);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mergeNominalStructures(module, topLevelStructures, 0, graphBuilder);
|
||||
for (var entry : subStructures.entrySet()) {
|
||||
mergeNominalStructures(module, entry.getValue(), entry.getKey().getFields().size(), graphBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
private static void mergeNominalStructures(WasmModule module, List<WasmStructure> structures, int parentFieldCount,
|
||||
GraphBuilder graphBuilder) {
|
||||
outer: for (var i = 0; i < structures.size(); i++) {
|
||||
for (var j = i + 1; j < structures.size(); j++) {
|
||||
var a = structures.get(i);
|
||||
var b = structures.get(j);
|
||||
if (areSameStructures(parentFieldCount, a, b)) {
|
||||
var p = module.types.indexOf(a);
|
||||
var q = module.types.indexOf(b);
|
||||
graphBuilder.addEdge(p, q);
|
||||
graphBuilder.addEdge(q, p);
|
||||
continue outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean areSameStructures(int start, WasmStructure a, WasmStructure b) {
|
||||
if (a.getFields().size() != b.getFields().size()) {
|
||||
return false;
|
||||
}
|
||||
for (var i = start; i < a.getFields().size(); i++) {
|
||||
if (a.getFields().get(i).getType() != b.getFields().get(i).getType()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class GraphBuilderVisitor implements WasmCompositeTypeVisitor {
|
||||
final WasmModule module;
|
||||
final GraphBuilder graphBuilder;
|
||||
|
Loading…
Reference in New Issue
Block a user