mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
wasm gc: avoid generation of unnecessary supertype functions
This commit is contained in:
parent
8e483245f5
commit
8d276f2efd
|
@ -157,10 +157,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
function.getBody().addAll(initializerFunctionStatements);
|
||||
initializerFunctionStatements.clear();
|
||||
for (var classInfo : classInfoMap.values()) {
|
||||
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
||||
supertypeFunction.setReferenced(true);
|
||||
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
||||
new WasmFunctionReference(supertypeFunction)));
|
||||
var req = metadataRequirements.getInfo(classInfo.getValueType());
|
||||
if (req != null && req.isAssignable()) {
|
||||
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
||||
supertypeFunction.setReferenced(true);
|
||||
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
||||
new WasmFunctionReference(supertypeFunction)));
|
||||
}
|
||||
function.getBody().add(setClassField(classInfo, CLASS_FIELD_OFFSET,
|
||||
new WasmGetGlobal(classClass.pointer)));
|
||||
if (classInfo.initializerPointer != null) {
|
||||
|
@ -265,9 +268,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
var req = metadataRequirements.getInfo(type);
|
||||
var name = req != null && req.name() ? ReflectionUtil.typeName(type.getKind()) : null;
|
||||
target.add(fillPrimitiveClass(
|
||||
classInfo.pointer,
|
||||
ReflectionUtil.typeName(type.getKind()),
|
||||
name,
|
||||
kind
|
||||
));
|
||||
};
|
||||
|
@ -401,10 +406,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
}
|
||||
|
||||
private WasmExpression fillPrimitiveClass(WasmGlobal global, String name, int kind) {
|
||||
var str = name != null
|
||||
? new WasmGetGlobal(strings.getStringConstant(name).global)
|
||||
: new WasmNullConstant(standardClasses.stringClass().getType());
|
||||
return new WasmCall(
|
||||
getCreatePrimitiveClassFunction(),
|
||||
new WasmGetGlobal(global),
|
||||
new WasmGetGlobal(strings.getStringConstant(name).global),
|
||||
str,
|
||||
new WasmInt32Constant(kind)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import org.teavm.dependency.DependencyInfo;
|
||||
import org.teavm.dependency.MethodDependencyInfo;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
public class ClassMetadataRequirements {
|
||||
private static final MethodReference GET_NAME_METHOD = new MethodReference(Class.class, "getName", String.class);
|
||||
|
@ -27,12 +28,14 @@ public class ClassMetadataRequirements {
|
|||
"getSimpleName", String.class);
|
||||
private static final MethodReference GET_SUPERCLASS_METHOD = new MethodReference(Class.class, "getSuperclass",
|
||||
Class.class);
|
||||
private static final MethodReference IS_ASSIGNABLE_METHOD = new MethodReference(Class.class, "isAssignableFrom",
|
||||
Class.class, boolean.class);
|
||||
private static final MethodReference GET_DECLARING_CLASS_METHOD = new MethodReference(Class.class,
|
||||
"getDeclaringClass", Class.class);
|
||||
private static final MethodReference GET_ENCLOSING_CLASS_METHOD = new MethodReference(Class.class,
|
||||
"getEnclosingClass", Class.class);
|
||||
private static final ClassInfo EMPTY_INFO = new ClassInfo();
|
||||
private Map<String, ClassInfo> requirements = new HashMap<>();
|
||||
private Map<ValueType, ClassInfo> requirements = new HashMap<>();
|
||||
|
||||
public ClassMetadataRequirements(DependencyInfo dependencyInfo) {
|
||||
MethodDependencyInfo getNameMethod = dependencyInfo.getMethod(GET_NAME_METHOD);
|
||||
|
@ -45,7 +48,7 @@ public class ClassMetadataRequirements {
|
|||
String[] classNames = getSimpleNameMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
addClassesRequiringName(requirements, classNames);
|
||||
for (String className : classNames) {
|
||||
ClassInfo classInfo = requirements.computeIfAbsent(className, k -> new ClassInfo());
|
||||
ClassInfo classInfo = requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo());
|
||||
classInfo.simpleName = true;
|
||||
classInfo.enclosingClass = true;
|
||||
}
|
||||
|
@ -53,9 +56,17 @@ public class ClassMetadataRequirements {
|
|||
|
||||
var getSuperclassMethod = dependencyInfo.getMethod(GET_SUPERCLASS_METHOD);
|
||||
if (getSuperclassMethod != null) {
|
||||
String[] classNames = getSuperclassMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
for (String className : classNames) {
|
||||
requirements.computeIfAbsent(className, k -> new ClassInfo()).declaringClass = true;
|
||||
var classNames = getSuperclassMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
for (var className : classNames) {
|
||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).declaringClass = true;
|
||||
}
|
||||
}
|
||||
|
||||
var isAssignableMethod = dependencyInfo.getMethod(IS_ASSIGNABLE_METHOD);
|
||||
if (isAssignableMethod != null) {
|
||||
var classNames = getSuperclassMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
for (var className : classNames) {
|
||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).isAssignable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +74,7 @@ public class ClassMetadataRequirements {
|
|||
if (getDeclaringClassMethod != null) {
|
||||
String[] classNames = getDeclaringClassMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
for (String className : classNames) {
|
||||
requirements.computeIfAbsent(className, k -> new ClassInfo()).declaringClass = true;
|
||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).declaringClass = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,12 +82,16 @@ public class ClassMetadataRequirements {
|
|||
if (getEnclosingClassMethod != null) {
|
||||
String[] classNames = getEnclosingClassMethod.getVariable(0).getClassValueNode().getTypes();
|
||||
for (String className : classNames) {
|
||||
requirements.computeIfAbsent(className, k -> new ClassInfo()).enclosingClass = true;
|
||||
requirements.computeIfAbsent(decodeType(className), k -> new ClassInfo()).enclosingClass = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Info getInfo(String className) {
|
||||
return getInfo(ValueType.object(className));
|
||||
}
|
||||
|
||||
public Info getInfo(ValueType className) {
|
||||
ClassInfo result = requirements.get(className);
|
||||
if (result == null) {
|
||||
result = EMPTY_INFO;
|
||||
|
@ -84,19 +99,19 @@ public class ClassMetadataRequirements {
|
|||
return result;
|
||||
}
|
||||
|
||||
private void addClassesRequiringName(Map<String, ClassInfo> target, String[] source) {
|
||||
private void addClassesRequiringName(Map<ValueType, ClassInfo> target, String[] source) {
|
||||
for (String typeName : source) {
|
||||
if (typeName.startsWith("[")) {
|
||||
if (!typeName.endsWith(";")) {
|
||||
continue;
|
||||
}
|
||||
int index = 0;
|
||||
while (typeName.charAt(index) == '[') {
|
||||
++index;
|
||||
}
|
||||
typeName = typeName.substring(index, typeName.length() - 1).replace('/', '.');
|
||||
}
|
||||
target.computeIfAbsent(typeName, k -> new ClassInfo()).name = true;
|
||||
target.computeIfAbsent(decodeType(typeName), k -> new ClassInfo()).name = true;
|
||||
}
|
||||
}
|
||||
|
||||
private ValueType decodeType(String typeName) {
|
||||
if (typeName.startsWith("[")) {
|
||||
return ValueType.parseIfPossible(typeName);
|
||||
} else if (typeName.startsWith("~")) {
|
||||
return ValueType.parseIfPossible(typeName.substring(1));
|
||||
} else {
|
||||
return ValueType.object(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +121,7 @@ public class ClassMetadataRequirements {
|
|||
boolean declaringClass;
|
||||
boolean enclosingClass;
|
||||
boolean superclass;
|
||||
boolean isAssignable;
|
||||
|
||||
@Override
|
||||
public boolean name() {
|
||||
|
@ -131,6 +147,11 @@ public class ClassMetadataRequirements {
|
|||
public boolean superclass() {
|
||||
return superclass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignable() {
|
||||
return isAssignable;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Info {
|
||||
|
@ -143,5 +164,7 @@ public class ClassMetadataRequirements {
|
|||
boolean enclosingClass();
|
||||
|
||||
boolean superclass();
|
||||
|
||||
boolean isAssignable();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user