Add static GC roots

This commit is contained in:
Alexey Andreev 2016-09-08 14:47:48 +03:00
parent f79716d53d
commit f7296e0389
2 changed files with 35 additions and 3 deletions

View File

@ -30,6 +30,7 @@ import org.teavm.backend.wasm.binary.DataPrimitives;
import org.teavm.backend.wasm.binary.DataStructure;
import org.teavm.backend.wasm.binary.DataType;
import org.teavm.backend.wasm.binary.DataValue;
import org.teavm.common.IntegerArray;
import org.teavm.interop.Address;
import org.teavm.interop.Function;
import org.teavm.interop.Structure;
@ -70,6 +71,8 @@ public class WasmClassGenerator {
DataPrimitives.INT, /* isInstance function */
DataPrimitives.ADDRESS, /* parent */
DataPrimitives.ADDRESS /* layout */);
private IntegerArray staticGcRoots = new IntegerArray(1);
private int staticGcRootsAddress;
private static final int CLASS_SIZE = 1;
private static final int CLASS_FLAGS = 2;
@ -203,10 +206,9 @@ public class WasmClassGenerator {
List<FieldReference> fields = getReferenceFields(binaryData.cls);
if (!fields.isEmpty()) {
header.setAddress(CLASS_LAYOUT, binaryWriter.getAddress());
DataValue layoutSize = DataPrimitives.SHORT.createValue();
layoutSize.setShort(0, (short) fields.size());
binaryWriter.append(layoutSize);
header.setAddress(CLASS_LAYOUT, binaryWriter.append(layoutSize));
for (FieldReference field : fields) {
DataValue layoutElement = DataPrimitives.SHORT.createValue();
layoutElement.setShort(0, (short) binaryData.fieldLayout.get(field.getFieldName()));
@ -214,6 +216,10 @@ public class WasmClassGenerator {
}
}
for (FieldReference field : getStaticReferenceFields(binaryData.cls)) {
staticGcRoots.add(binaryData.fieldLayout.get(field.getFieldName()));
}
return vtable != null ? wrapper : header;
}
@ -225,6 +231,14 @@ public class WasmClassGenerator {
.collect(Collectors.toList());
}
private List<FieldReference> getStaticReferenceFields(ClassReader cls) {
return cls.getFields().stream()
.filter(field -> field.hasModifier(ElementModifier.STATIC))
.filter(field -> !(field.getType() instanceof ValueType.Primitive))
.map(field -> field.getReference())
.collect(Collectors.toList());
}
private void fillVirtualTable(VirtualTable vtable, DataValue array) {
int index = 0;
for (VirtualTableEntry vtableEntry : vtable.getEntries().values()) {
@ -392,6 +406,22 @@ public class WasmClassGenerator {
}
}
}
writeStaticGcRoots();
}
public int getStaticGcRootsAddress() {
return staticGcRootsAddress;
}
private void writeStaticGcRoots() {
DataValue sizeValue = DataPrimitives.LONG.createValue();
sizeValue.setLong(0, staticGcRoots.size());
staticGcRootsAddress = binaryWriter.append(sizeValue);
for (int gcRoot : staticGcRoots.getAll()) {
DataValue value = DataPrimitives.ADDRESS.createValue();
value.setAddress(0, gcRoot);
binaryWriter.append(value);
}
}
public boolean hasClinit(String className) {

View File

@ -24,7 +24,7 @@ public final class Allocator {
private Allocator() {
}
private static Address address = initialize();
static Address address = initialize();
private static native Address initialize();
@ -64,4 +64,6 @@ public final class Allocator {
public static native void removeGcRoot(int index);
public static native void releaseStack(int size);
public static native Address getStaticGcRoots();
}