mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Wasm: don't generate class metadata if it's not used. Don't generate names and call site metadata in minified mode
This commit is contained in:
parent
3f2c52000f
commit
0e7c1e5ef9
|
@ -129,6 +129,7 @@ import org.teavm.model.MethodReader;
|
|||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Program;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.analysis.ClassMetadataRequirements;
|
||||
import org.teavm.model.classes.TagRegistry;
|
||||
import org.teavm.model.classes.VirtualTableBuilder;
|
||||
import org.teavm.model.classes.VirtualTableProvider;
|
||||
|
@ -184,6 +185,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
private CheckInstructionTransformation checkTransformation = new CheckInstructionTransformation();
|
||||
private int minHeapSize = 2 * 1024 * 1024;
|
||||
private int maxHeapSize = 128 * 1024 * 1024;
|
||||
private boolean obfuscated;
|
||||
|
||||
@Override
|
||||
public void setController(TeaVMTargetController controller) {
|
||||
|
@ -272,6 +274,10 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
this.maxHeapSize = maxHeapSize;
|
||||
}
|
||||
|
||||
public void setObfuscated(boolean obfuscated) {
|
||||
this.obfuscated = obfuscated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contributeDependencies(DependencyAnalyzer dependencyAnalyzer) {
|
||||
for (Class<?> type : Arrays.asList(int.class, long.class, float.class, double.class)) {
|
||||
|
@ -374,8 +380,10 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
BinaryWriter binaryWriter = new BinaryWriter(256);
|
||||
NameProvider names = new NameProviderWithSpecialNames(new WasmNameProvider(),
|
||||
controller.getUnprocessedClassSource());
|
||||
ClassMetadataRequirements metadataRequirements = new ClassMetadataRequirements(controller.getDependencyInfo());
|
||||
WasmClassGenerator classGenerator = new WasmClassGenerator(classes, controller.getUnprocessedClassSource(),
|
||||
vtableProvider, tagRegistry, binaryWriter, names);
|
||||
vtableProvider, tagRegistry, binaryWriter, names, metadataRequirements,
|
||||
controller.getClassInitializerInfo());
|
||||
|
||||
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false);
|
||||
WasmStringPool stringPool = classGenerator.getStringPool();
|
||||
|
@ -417,7 +425,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
context.addIntrinsic(mutatorIntrinsic);
|
||||
context.addIntrinsic(new ShadowStackIntrinsic());
|
||||
ExceptionHandlingIntrinsic exceptionHandlingIntrinsic = new ExceptionHandlingIntrinsic(binaryWriter,
|
||||
classGenerator, stringPool);
|
||||
classGenerator, stringPool, obfuscated);
|
||||
context.addIntrinsic(exceptionHandlingIntrinsic);
|
||||
|
||||
WasmGenerator generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter);
|
||||
|
@ -471,7 +479,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
|||
}
|
||||
|
||||
WasmBinaryWriter writer = new WasmBinaryWriter();
|
||||
WasmBinaryRenderer renderer = new WasmBinaryRenderer(writer, version);
|
||||
WasmBinaryRenderer renderer = new WasmBinaryRenderer(writer, version, obfuscated);
|
||||
renderer.render(module);
|
||||
|
||||
try (OutputStream output = buildTarget.createResource(outputName)) {
|
||||
|
|
|
@ -62,11 +62,14 @@ public class CallSiteBinaryGenerator {
|
|||
private WasmClassGenerator classGenerator;
|
||||
private WasmStringPool stringPool;
|
||||
private ObjectIntMap<String> stringIndirectPointerCache = new ObjectIntHashMap<>();
|
||||
private boolean obfuscated;
|
||||
|
||||
public CallSiteBinaryGenerator(BinaryWriter writer, WasmClassGenerator classGenerator, WasmStringPool stringPool) {
|
||||
public CallSiteBinaryGenerator(BinaryWriter writer, WasmClassGenerator classGenerator, WasmStringPool stringPool,
|
||||
boolean obfuscated) {
|
||||
this.writer = writer;
|
||||
this.classGenerator = classGenerator;
|
||||
this.stringPool = stringPool;
|
||||
this.obfuscated = obfuscated;
|
||||
}
|
||||
|
||||
public int writeCallSites(List<? extends CallSiteDescriptor> callSites) {
|
||||
|
@ -120,52 +123,60 @@ public class CallSiteBinaryGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
CallSiteLocation[] locations = callSite.getLocations();
|
||||
LocationList prevList = null;
|
||||
int locationAddress = 0;
|
||||
int previousLocationAddress = 0;
|
||||
for (int i = locations.length - 1; i >= 0; --i) {
|
||||
LocationList list = new LocationList(locations[i], prevList);
|
||||
locationAddress = locationCache.getOrDefault(list, 0);
|
||||
if (locationAddress == 0) {
|
||||
DataValue binaryLocation = locationStructure.createValue();
|
||||
locationAddress = writer.append(binaryLocation);
|
||||
locationCache.put(list, locationAddress);
|
||||
CallSiteLocation location = list.location;
|
||||
MethodLocation methodLocation = new MethodLocation(location.getFileName(), location.getClassName(),
|
||||
location.getMethodName());
|
||||
int methodLocationAddress = methodLocationCache.getOrDefault(methodLocation, -1);
|
||||
if (methodLocationAddress < 0) {
|
||||
DataValue binaryMethodLocation = methodLocationStructure.createValue();
|
||||
methodLocationAddress = writer.append(binaryMethodLocation);
|
||||
methodLocationCache.put(methodLocation, methodLocationAddress);
|
||||
if (location.getFileName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_FILE,
|
||||
getStringIndirectPointer(location.getFileName()));
|
||||
}
|
||||
if (location.getClassName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_CLASS,
|
||||
getStringIndirectPointer(location.getClassName()));
|
||||
}
|
||||
if (location.getMethodName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_METHOD,
|
||||
getStringIndirectPointer(location.getMethodName()));
|
||||
}
|
||||
}
|
||||
|
||||
binaryLocation.setAddress(LOCATION_METHOD, methodLocationAddress);
|
||||
binaryLocation.setInt(LOCATION_LINE, location.getLineNumber());
|
||||
binaryLocation.setAddress(LOCATION_NEXT, previousLocationAddress);
|
||||
}
|
||||
previousLocationAddress = locationAddress;
|
||||
if (!obfuscated) {
|
||||
binaryCallSite.setAddress(CALL_SITE_LOCATION,
|
||||
generateLocations(methodLocationCache, locationCache, callSite));
|
||||
}
|
||||
|
||||
binaryCallSite.setAddress(CALL_SITE_LOCATION, locationAddress);
|
||||
}
|
||||
|
||||
return firstCallSite;
|
||||
}
|
||||
|
||||
private int generateLocations(ObjectIntMap<MethodLocation> methodLocationCache,
|
||||
ObjectIntMap<LocationList> locationCache, CallSiteDescriptor callSite) {
|
||||
CallSiteLocation[] locations = callSite.getLocations();
|
||||
LocationList prevList = null;
|
||||
int locationAddress = 0;
|
||||
int previousLocationAddress = 0;
|
||||
for (int i = locations.length - 1; i >= 0; --i) {
|
||||
LocationList list = new LocationList(locations[i], prevList);
|
||||
locationAddress = locationCache.getOrDefault(list, 0);
|
||||
if (locationAddress == 0) {
|
||||
DataValue binaryLocation = locationStructure.createValue();
|
||||
locationAddress = writer.append(binaryLocation);
|
||||
locationCache.put(list, locationAddress);
|
||||
CallSiteLocation location = list.location;
|
||||
MethodLocation methodLocation = new MethodLocation(location.getFileName(),
|
||||
location.getClassName(), location.getMethodName());
|
||||
int methodLocationAddress = methodLocationCache.getOrDefault(methodLocation, -1);
|
||||
if (methodLocationAddress < 0) {
|
||||
DataValue binaryMethodLocation = methodLocationStructure.createValue();
|
||||
methodLocationAddress = writer.append(binaryMethodLocation);
|
||||
methodLocationCache.put(methodLocation, methodLocationAddress);
|
||||
if (location.getFileName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_FILE,
|
||||
getStringIndirectPointer(location.getFileName()));
|
||||
}
|
||||
if (location.getClassName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_CLASS,
|
||||
getStringIndirectPointer(location.getClassName()));
|
||||
}
|
||||
if (location.getMethodName() != null) {
|
||||
binaryMethodLocation.setAddress(METHOD_LOCATION_METHOD,
|
||||
getStringIndirectPointer(location.getMethodName()));
|
||||
}
|
||||
}
|
||||
|
||||
binaryLocation.setAddress(LOCATION_METHOD, methodLocationAddress);
|
||||
binaryLocation.setInt(LOCATION_LINE, location.getLineNumber());
|
||||
binaryLocation.setAddress(LOCATION_NEXT, previousLocationAddress);
|
||||
}
|
||||
previousLocationAddress = locationAddress;
|
||||
}
|
||||
|
||||
return locationAddress;
|
||||
}
|
||||
|
||||
private int getStringIndirectPointer(String str) {
|
||||
int result = stringIndirectPointerCache.getOrDefault(str, -1);
|
||||
if (result < 0) {
|
||||
|
|
|
@ -43,6 +43,8 @@ import org.teavm.model.FieldReference;
|
|||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.model.analysis.ClassInitializerInfo;
|
||||
import org.teavm.model.analysis.ClassMetadataRequirements;
|
||||
import org.teavm.model.classes.TagRegistry;
|
||||
import org.teavm.model.classes.VirtualTable;
|
||||
import org.teavm.model.classes.VirtualTableEntry;
|
||||
|
@ -91,6 +93,8 @@ public class WasmClassGenerator {
|
|||
private int staticGcRootsAddress;
|
||||
private int classesAddress;
|
||||
private int classCount;
|
||||
private ClassMetadataRequirements metadataRequirements;
|
||||
private ClassInitializerInfo classInitializerInfo;
|
||||
|
||||
private static final int CLASS_SIZE = 1;
|
||||
private static final int CLASS_FLAGS = 2;
|
||||
|
@ -110,7 +114,8 @@ public class WasmClassGenerator {
|
|||
|
||||
public WasmClassGenerator(ClassReaderSource processedClassSource, ClassReaderSource classSource,
|
||||
VirtualTableProvider vtableProvider, TagRegistry tagRegistry, BinaryWriter binaryWriter,
|
||||
NameProvider names) {
|
||||
NameProvider names, ClassMetadataRequirements metadataRequirements,
|
||||
ClassInitializerInfo classInitializerInfo) {
|
||||
this.processedClassSource = processedClassSource;
|
||||
this.classSource = classSource;
|
||||
this.vtableProvider = vtableProvider;
|
||||
|
@ -118,6 +123,8 @@ public class WasmClassGenerator {
|
|||
this.binaryWriter = binaryWriter;
|
||||
this.stringPool = new WasmStringPool(this, binaryWriter);
|
||||
this.names = names;
|
||||
this.metadataRequirements = metadataRequirements;
|
||||
this.classInitializerInfo = classInitializerInfo;
|
||||
}
|
||||
|
||||
public WasmStringPool getStringPool() {
|
||||
|
@ -259,6 +266,7 @@ public class WasmClassGenerator {
|
|||
: 0;
|
||||
|
||||
String name = ((ValueType.Object) binaryData.type).getClassName();
|
||||
ClassMetadataRequirements.Info requirements = metadataRequirements.getInfo(name);
|
||||
int flags = 0;
|
||||
|
||||
VirtualTable vtable = vtableProvider.lookup(name);
|
||||
|
@ -279,7 +287,8 @@ public class WasmClassGenerator {
|
|||
int tag = ranges.stream().mapToInt(range -> range.lower).min().orElse(0);
|
||||
header.setInt(CLASS_TAG, tag);
|
||||
header.setInt(CLASS_CANARY, RuntimeClass.computeCanary(occupiedSize, tag));
|
||||
header.setAddress(CLASS_NAME, stringPool.getStringPointer(name));
|
||||
int nameAddress = requirements.name() ? stringPool.getStringPointer(name) : 0;
|
||||
header.setAddress(CLASS_NAME, nameAddress);
|
||||
header.setInt(CLASS_IS_INSTANCE, functionTable.size());
|
||||
functionTable.add(names.forSupertypeFunction(ValueType.object(name)));
|
||||
header.setAddress(CLASS_PARENT, parentPtr);
|
||||
|
@ -287,14 +296,16 @@ public class WasmClassGenerator {
|
|||
ClassReader cls = processedClassSource.get(name);
|
||||
|
||||
if (cls != null) {
|
||||
if (cls.getSimpleName() != null) {
|
||||
if (cls.getSimpleName() != null && requirements.simpleName()) {
|
||||
header.setAddress(CLASS_SIMPLE_NAME, stringPool.getStringPointer(cls.getSimpleName()));
|
||||
}
|
||||
|
||||
if (cls.getOwnerName() != null && processedClassSource.get(cls.getOwnerName()) != null) {
|
||||
if (cls.getOwnerName() != null && processedClassSource.get(cls.getOwnerName()) != null
|
||||
&& requirements.enclosingClass()) {
|
||||
header.setAddress(CLASS_ENCLOSING_CLASS, getClassPointer(ValueType.object(cls.getOwnerName())));
|
||||
}
|
||||
if (cls.getDeclaringClassName() != null && processedClassSource.get(cls.getDeclaringClassName()) != null) {
|
||||
if (cls.getDeclaringClassName() != null && processedClassSource.get(cls.getDeclaringClassName()) != null
|
||||
&& requirements.declaringClass()) {
|
||||
header.setAddress(CLASS_DECLARING_CLASS,
|
||||
getClassPointer(ValueType.object(cls.getDeclaringClassName())));
|
||||
}
|
||||
|
@ -332,7 +343,8 @@ public class WasmClassGenerator {
|
|||
}
|
||||
|
||||
if (cls != null && binaryData.start >= 0
|
||||
&& cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null) {
|
||||
&& cls.getMethod(new MethodDescriptor("<clinit>", ValueType.VOID)) != null
|
||||
&& classInitializerInfo.isDynamicInitializer(name)) {
|
||||
header.setInt(CLASS_INIT, functionTable.size());
|
||||
functionTable.add(names.forClassInitializer(name));
|
||||
} else {
|
||||
|
|
|
@ -39,8 +39,8 @@ public class ExceptionHandlingIntrinsic implements WasmIntrinsic {
|
|||
private List<WasmInt32Constant> constants = new ArrayList<>();
|
||||
|
||||
public ExceptionHandlingIntrinsic(BinaryWriter binaryWriter, WasmClassGenerator classGenerator,
|
||||
WasmStringPool stringPool) {
|
||||
callSiteBinaryGenerator = new CallSiteBinaryGenerator(binaryWriter, classGenerator, stringPool);
|
||||
WasmStringPool stringPool, boolean obfuscated) {
|
||||
callSiteBinaryGenerator = new CallSiteBinaryGenerator(binaryWriter, classGenerator, stringPool, obfuscated);
|
||||
this.classGenerator = classGenerator;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,10 +49,12 @@ public class WasmBinaryRenderer {
|
|||
private List<WasmSignature> signatures = new ArrayList<>();
|
||||
private Map<WasmSignature, Integer> signatureIndexes = new HashMap<>();
|
||||
private Map<String, Integer> functionIndexes = new HashMap<>();
|
||||
private boolean obfuscated;
|
||||
|
||||
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version) {
|
||||
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated) {
|
||||
this.output = output;
|
||||
this.version = version;
|
||||
this.obfuscated = obfuscated;
|
||||
}
|
||||
|
||||
public void render(WasmModule module) {
|
||||
|
@ -73,7 +75,9 @@ public class WasmBinaryRenderer {
|
|||
renderElement(module);
|
||||
renderCode(module);
|
||||
renderData(module);
|
||||
renderNames(module);
|
||||
if (!obfuscated) {
|
||||
renderNames(module);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderSignatures(WasmModule module) {
|
||||
|
|
|
@ -332,6 +332,7 @@ public class TeaVMTool {
|
|||
webAssemblyTarget.setVersion(wasmVersion);
|
||||
webAssemblyTarget.setMinHeapSize(minHeapSize);
|
||||
webAssemblyTarget.setMaxHeapSize(maxHeapSize);
|
||||
webAssemblyTarget.setObfuscated(minifying);
|
||||
return webAssemblyTarget;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user