mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
wasm gc: reduce size of array construction
This commit is contained in:
parent
e5d6603503
commit
86e8cfd0db
|
@ -254,7 +254,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
new WasmFunctionReference(supertypeFunction)));
|
new WasmFunctionReference(supertypeFunction)));
|
||||||
}
|
}
|
||||||
if (req.newArray()) {
|
if (req.newArray()) {
|
||||||
var newArrayFunction = newArrayGenerator.generateNewArrayFunction(classInfo.getValueType());
|
var newArrayFunction = getArrayConstructor(ValueType.arrayOf(classInfo.getValueType()));
|
||||||
newArrayFunction.setReferenced(true);
|
newArrayFunction.setReferenced(true);
|
||||||
function.getBody().add(setClassField(classInfo, classNewArrayOffset,
|
function.getBody().add(setClassField(classInfo, classNewArrayOffset,
|
||||||
new WasmFunctionReference(newArrayFunction)));
|
new WasmFunctionReference(newArrayFunction)));
|
||||||
|
@ -350,6 +350,15 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
return classInfo;
|
return classInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WasmFunction getArrayConstructor(ValueType.Array type) {
|
||||||
|
var arrayInfo = getClassInfo(type);
|
||||||
|
if (arrayInfo.newArrayFunction == null) {
|
||||||
|
arrayInfo.newArrayFunction = newArrayGenerator.generateNewArrayFunction(type.getItemType());
|
||||||
|
}
|
||||||
|
return arrayInfo.newArrayFunction;
|
||||||
|
}
|
||||||
|
|
||||||
public int getClassTagOffset() {
|
public int getClassTagOffset() {
|
||||||
standardClasses.classClass().getStructure().init();
|
standardClasses.classClass().getStructure().init();
|
||||||
return classTagOffset;
|
return classTagOffset;
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.backend.wasm.generate.gc.classes;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.teavm.backend.wasm.model.WasmArray;
|
import org.teavm.backend.wasm.model.WasmArray;
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
import org.teavm.backend.wasm.model.WasmStructure;
|
import org.teavm.backend.wasm.model.WasmStructure;
|
||||||
import org.teavm.backend.wasm.model.WasmType;
|
import org.teavm.backend.wasm.model.WasmType;
|
||||||
|
@ -31,6 +32,7 @@ public class WasmGCClassInfo {
|
||||||
WasmGlobal pointer;
|
WasmGlobal pointer;
|
||||||
WasmGlobal initializerPointer;
|
WasmGlobal initializerPointer;
|
||||||
Consumer<List<WasmExpression>> initializer;
|
Consumer<List<WasmExpression>> initializer;
|
||||||
|
WasmFunction newArrayFunction;
|
||||||
|
|
||||||
WasmGCClassInfo(ValueType valueType) {
|
WasmGCClassInfo(ValueType valueType) {
|
||||||
this.valueType = valueType;
|
this.valueType = valueType;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generate.gc.classes;
|
package org.teavm.backend.wasm.generate.gc.classes;
|
||||||
|
|
||||||
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
import org.teavm.backend.wasm.model.WasmGlobal;
|
import org.teavm.backend.wasm.model.WasmGlobal;
|
||||||
import org.teavm.backend.wasm.model.WasmStructure;
|
import org.teavm.backend.wasm.model.WasmStructure;
|
||||||
import org.teavm.model.FieldReference;
|
import org.teavm.model.FieldReference;
|
||||||
|
@ -34,6 +35,8 @@ public interface WasmGCClassInfoProvider {
|
||||||
|
|
||||||
WasmGlobal getStaticFieldLocation(FieldReference fieldRef);
|
WasmGlobal getStaticFieldLocation(FieldReference fieldRef);
|
||||||
|
|
||||||
|
WasmFunction getArrayConstructor(ValueType.Array type);
|
||||||
|
|
||||||
int getVirtualMethodsOffset();
|
int getVirtualMethodsOffset();
|
||||||
|
|
||||||
int getClassArrayItemOffset();
|
int getClassArrayItemOffset();
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generate.gc.classes;
|
package org.teavm.backend.wasm.generate.gc.classes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
|
@ -44,15 +45,19 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
||||||
var function = new WasmFunction(getNewArrayFunctionType());
|
var classInfo = classInfoProvider.getClassInfo(ValueType.arrayOf(itemType));
|
||||||
|
var functionType = new WasmFunctionType(null, classInfo.getType(), List.of(WasmType.INT32));
|
||||||
|
module.types.add(functionType);
|
||||||
|
functionType.setFinal(true);
|
||||||
|
functionType.getSupertypes().add(getNewArrayFunctionType());
|
||||||
|
var function = new WasmFunction(functionType);
|
||||||
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">@new"));
|
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">@new"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
||||||
function.add(sizeLocal);
|
function.add(sizeLocal);
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var tempVars = new TemporaryVariablePool(function);
|
||||||
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
||||||
var targetVar = new WasmLocal(classInfoProvider.getClassInfo(ValueType.arrayOf(itemType)).getType(),
|
var targetVar = new WasmLocal(classInfo.getType(), "result");
|
||||||
"result");
|
|
||||||
function.add(targetVar);
|
function.add(targetVar);
|
||||||
genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
||||||
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
||||||
|
@ -63,6 +68,7 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
if (newArrayFunctionType == null) {
|
if (newArrayFunctionType == null) {
|
||||||
newArrayFunctionType = functionTypes.of(classInfoProvider.getClassInfo("java.lang.Object").getType(),
|
newArrayFunctionType = functionTypes.of(classInfoProvider.getClassInfo("java.lang.Object").getType(),
|
||||||
WasmType.INT32);
|
WasmType.INT32);
|
||||||
|
newArrayFunctionType.setFinal(false);
|
||||||
}
|
}
|
||||||
return newArrayFunctionType;
|
return newArrayFunctionType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generate.gc.methods;
|
package org.teavm.backend.wasm.generate.gc.methods;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import org.teavm.ast.ArrayFromDataExpr;
|
||||||
import org.teavm.ast.ArrayType;
|
import org.teavm.ast.ArrayType;
|
||||||
import org.teavm.ast.BinaryExpr;
|
import org.teavm.ast.BinaryExpr;
|
||||||
import org.teavm.ast.CastExpr;
|
import org.teavm.ast.CastExpr;
|
||||||
|
@ -25,6 +27,7 @@ import org.teavm.ast.Expr;
|
||||||
import org.teavm.ast.InstanceOfExpr;
|
import org.teavm.ast.InstanceOfExpr;
|
||||||
import org.teavm.ast.InvocationExpr;
|
import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.ast.InvocationType;
|
import org.teavm.ast.InvocationType;
|
||||||
|
import org.teavm.ast.NewArrayExpr;
|
||||||
import org.teavm.ast.QualificationExpr;
|
import org.teavm.ast.QualificationExpr;
|
||||||
import org.teavm.ast.SubscriptExpr;
|
import org.teavm.ast.SubscriptExpr;
|
||||||
import org.teavm.ast.TryCatchStatement;
|
import org.teavm.ast.TryCatchStatement;
|
||||||
|
@ -242,6 +245,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
return new WasmIsNull(value);
|
return new WasmIsNull(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected WasmExpression nullCheck(Expr value, TextLocation location) {
|
protected WasmExpression nullCheck(Expr value, TextLocation location) {
|
||||||
var block = new WasmBlock(false);
|
var block = new WasmBlock(false);
|
||||||
block.setLocation(location);
|
block.setLocation(location);
|
||||||
|
@ -360,6 +364,42 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(ArrayFromDataExpr expr) {
|
||||||
|
var wasmArrayType = (WasmType.CompositeReference) mapType(ValueType.arrayOf(expr.getType()));
|
||||||
|
var block = new WasmBlock(false);
|
||||||
|
block.setType(wasmArrayType);
|
||||||
|
var wasmArrayStruct = (WasmStructure) wasmArrayType.composite;
|
||||||
|
var wasmArrayDataType = (WasmType.CompositeReference) wasmArrayStruct.getFields()
|
||||||
|
.get(WasmGCClassInfoProvider.ARRAY_DATA_FIELD_OFFSET).getUnpackedType();
|
||||||
|
var wasmArray = (WasmArray) wasmArrayDataType.composite;
|
||||||
|
var array = tempVars.acquire(wasmArrayType);
|
||||||
|
|
||||||
|
generationUtil.allocateArrayWithElements(expr.getType(), () -> {
|
||||||
|
var items = new ArrayList<WasmExpression>();
|
||||||
|
for (int i = 0; i < expr.getData().size(); ++i) {
|
||||||
|
accept(expr.getData().get(i), wasmArray.getElementType().asUnpackedType());
|
||||||
|
items.add(result);
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}, expr.getLocation(), array, block.getBody());
|
||||||
|
|
||||||
|
block.getBody().add(new WasmGetLocal(array));
|
||||||
|
block.setLocation(expr.getLocation());
|
||||||
|
tempVars.release(array);
|
||||||
|
|
||||||
|
result = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NewArrayExpr expr) {
|
||||||
|
accept(expr.getLength(), WasmType.INT32);
|
||||||
|
var function = context.classInfoProvider().getArrayConstructor(ValueType.arrayOf(expr.getType()));
|
||||||
|
var call = new WasmCall(function, result);
|
||||||
|
call.setLocation(expr.getLocation());
|
||||||
|
result = call;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
protected void allocateArray(ValueType itemType, Supplier<WasmExpression> length, TextLocation location,
|
||||||
WasmLocal local, List<WasmExpression> target) {
|
WasmLocal local, List<WasmExpression> target) {
|
||||||
|
|
|
@ -240,7 +240,7 @@ public abstract class ValueType implements Serializable {
|
||||||
return new Object(cls);
|
return new Object(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValueType arrayOf(ValueType type) {
|
public static ValueType.Array arrayOf(ValueType type) {
|
||||||
return new Array(type);
|
return new Array(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user