wasm: don't generate separate declarations for methods in DWARF

This commit is contained in:
Alexey Andreev 2023-08-24 06:45:41 +02:00
parent 49485efdff
commit e576a985dd
3 changed files with 37 additions and 94 deletions

View File

@ -20,7 +20,6 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_FLOAT;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_SIGNED; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_SIGNED;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_UTF; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_UTF;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_BYTE_SIZE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_BYTE_SIZE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DECLARATION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_ENCODING; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_ENCODING;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOCATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOCATION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME;
@ -28,7 +27,6 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA1; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA1;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA2; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA2;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_FLAG_PRESENT;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_REF4; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_REF4;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_STRP; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_STRP;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_ADDR; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_ADDR;
@ -38,7 +36,6 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_CLASS_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_INHERITANCE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_INHERITANCE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_NAMESPACE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_NAMESPACE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_POINTER_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_POINTER_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_UNSPECIFIED_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_UNSPECIFIED_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE;
import java.util.ArrayList; import java.util.ArrayList;
@ -51,6 +48,7 @@ import org.teavm.backend.wasm.debug.info.VariableType;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter; import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
import org.teavm.backend.wasm.dwarf.DwarfPlaceholder; import org.teavm.backend.wasm.dwarf.DwarfPlaceholder;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.PrimitiveType; import org.teavm.model.PrimitiveType;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
@ -65,7 +63,6 @@ public class DwarfClassGenerator {
private DwarfAbbreviation nsAbbrev; private DwarfAbbreviation nsAbbrev;
private DwarfAbbreviation classTypeAbbrev; private DwarfAbbreviation classTypeAbbrev;
private DwarfAbbreviation inheritanceAbbrev; private DwarfAbbreviation inheritanceAbbrev;
private DwarfAbbreviation methodAbbrev;
private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length]; private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length];
private DwarfPlaceholder unspecifiedType; private DwarfPlaceholder unspecifiedType;
private DwarfAbbreviation baseTypeAbbrev; private DwarfAbbreviation baseTypeAbbrev;
@ -73,10 +70,12 @@ public class DwarfClassGenerator {
private DwarfAbbreviation variableAbbrev; private DwarfAbbreviation variableAbbrev;
private List<Runnable> postponedWrites = new ArrayList<>(); private List<Runnable> postponedWrites = new ArrayList<>();
private ClassType classClass; private ClassType classClass;
private DwarfFunctionGenerator functionGen;
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
this.writer = writer; this.writer = writer;
this.strings = strings; this.strings = strings;
functionGen = new DwarfFunctionGenerator(this, writer, strings);
} }
public void flushTypes() { public void flushTypes() {
@ -117,16 +116,6 @@ public class DwarfClassGenerator {
flushTypes(); flushTypes();
} }
private DwarfAbbreviation getMethodAbbrev() {
if (methodAbbrev == null) {
methodAbbrev = writer.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DW_AT_DECLARATION).writeLEB(DW_FORM_FLAG_PRESENT);
});
}
return methodAbbrev;
}
private DwarfAbbreviation getNsAbbrev() { private DwarfAbbreviation getNsAbbrev() {
if (nsAbbrev == null) { if (nsAbbrev == null) {
nsAbbrev = writer.abbreviation(DW_TAG_NAMESPACE, true, data -> { nsAbbrev = writer.abbreviation(DW_TAG_NAMESPACE, true, data -> {
@ -391,18 +380,19 @@ public class DwarfClassGenerator {
public final String name; public final String name;
public boolean isStatic; public boolean isStatic;
public final MethodDescriptor descriptor; public final MethodDescriptor descriptor;
public final DwarfPlaceholder ref; public int startOffset;
public int endOffset;
public WasmFunction function;
private Subprogram(String name, MethodDescriptor descriptor) { private Subprogram(String name, MethodDescriptor descriptor) {
this.name = name; this.name = name;
this.descriptor = descriptor; this.descriptor = descriptor;
ref = writer.placeholder(4);
} }
private void write() { private void write() {
writer.mark(ref).tag(getMethodAbbrev()); if (function != null) {
writer.writeInt(strings.stringRef(name)); functionGen.writeContent(this);
writer.emptyTag(); }
} }
} }
} }

View File

@ -19,7 +19,6 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_HIGH_PC;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOCATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOCATION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOW_PC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOW_PC;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_SPECIFICATION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC;
@ -31,63 +30,46 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_FORMAL_PARAMETE
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE;
import org.teavm.backend.wasm.blob.Blob; import org.teavm.backend.wasm.blob.Blob;
import org.teavm.backend.wasm.blob.Marker;
import org.teavm.backend.wasm.debug.info.VariableType; import org.teavm.backend.wasm.debug.info.VariableType;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
public class DwarfFunctionGenerator { public class DwarfFunctionGenerator {
private DwarfClassGenerator classGen; private DwarfClassGenerator classGen;
private DwarfGenerator generator; private DwarfInfoWriter writer;
private WasmFunction function; private DwarfStrings strings;
private int offset;
private Marker endProgramMarker;
private DwarfAbbreviation methodAbbrev; private DwarfAbbreviation methodAbbrev;
private DwarfAbbreviation functionAbbrev;
private DwarfAbbreviation parameterAbbrev; private DwarfAbbreviation parameterAbbrev;
private DwarfAbbreviation variableAbbrev; private DwarfAbbreviation variableAbbrev;
private DwarfClassGenerator.Subprogram subprogram;
public DwarfFunctionGenerator(DwarfClassGenerator classGen, DwarfGenerator generator) { public DwarfFunctionGenerator(DwarfClassGenerator classGen, DwarfInfoWriter writer, DwarfStrings strings) {
this.classGen = classGen; this.classGen = classGen;
this.generator = generator; this.writer = writer;
this.strings = strings;
} }
public void begin(WasmFunction function, int offset) { public void writeContent(DwarfClassGenerator.Subprogram subprogram) {
if (function.getName() == null) { if (subprogram.function.getName() == null) {
return; return;
} }
subprogram = classGen.getSubprogram(function.getName()); writer.tag(getMethodAbbrev());
var writer = generator.getInfoWriter(); writer.writeInt(strings.stringRef(subprogram.name));
var strings = generator.strings; writer.writeInt(subprogram.startOffset);
writer.tag(subprogram != null ? getMethodAbbrev() : getFunctionAbbrev()); writer.writeInt(subprogram.endOffset);
if (subprogram != null) {
writer.ref(subprogram.ref, Blob::writeInt);
} else {
writer.writeInt(strings.stringRef(subprogram != null ? subprogram.name : function.getName()));
}
writer.writeInt(offset);
endProgramMarker = writer.marker();
writer.skip(4);
this.function = function; writeLocals(subprogram);
this.offset = offset;
writeLocals(); writer.emptyTag();
} }
private void writeLocals() { private void writeLocals(DwarfClassGenerator.Subprogram subprogram) {
if (subprogram == null) {
return;
}
var descriptor = subprogram.descriptor; var descriptor = subprogram.descriptor;
if (descriptor == null) { if (descriptor == null) {
return; return;
} }
var writer = generator.getInfoWriter(); var function = subprogram.function;
var strings = generator.strings;
var offset = subprogram.isStatic ? 0 : 1; var offset = subprogram.isStatic ? 0 : 1;
int count = Math.min(function.getLocalVariables().size() - offset, descriptor.parameterCount()); int count = Math.min(function.getLocalVariables().size() - offset, descriptor.parameterCount());
for (var i = 0; i < count; ++i) { for (var i = 0; i < count; ++i) {
@ -124,29 +106,10 @@ public class DwarfFunctionGenerator {
} }
} }
public void end(int size) {
if (function == null) {
return;
}
var writer = generator.getInfoWriter();
if (endProgramMarker != null) {
var backup = writer.marker();
endProgramMarker.rewind();
writer.writeInt(offset + size);
backup.rewind();
}
writer.emptyTag();
classGen.flushTypes();
subprogram = null;
endProgramMarker = null;
function = null;
}
private DwarfAbbreviation getMethodAbbrev() { private DwarfAbbreviation getMethodAbbrev() {
if (methodAbbrev == null) { if (methodAbbrev == null) {
methodAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> { methodAbbrev = writer.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DW_AT_SPECIFICATION).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR); data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR);
data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR); data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR);
}); });
@ -154,20 +117,9 @@ public class DwarfFunctionGenerator {
return methodAbbrev; return methodAbbrev;
} }
private DwarfAbbreviation getFunctionAbbrev() {
if (functionAbbrev == null) {
functionAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR);
data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR);
});
}
return functionAbbrev;
}
private DwarfAbbreviation getParameterAbbrev() { private DwarfAbbreviation getParameterAbbrev() {
if (parameterAbbrev == null) { if (parameterAbbrev == null) {
parameterAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_FORMAL_PARAMETER, false, data -> { parameterAbbrev = writer.abbreviation(DW_TAG_FORMAL_PARAMETER, false, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4);
data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC); data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC);
@ -178,7 +130,7 @@ public class DwarfFunctionGenerator {
private DwarfAbbreviation getVariableAbbrev() { private DwarfAbbreviation getVariableAbbrev() {
if (variableAbbrev == null) { if (variableAbbrev == null) {
variableAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_VARIABLE, false, data -> { variableAbbrev = writer.abbreviation(DW_TAG_VARIABLE, false, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4);
data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC); data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC);

View File

@ -26,7 +26,6 @@ import java.util.stream.Collectors;
import org.teavm.backend.wasm.debug.DebugLines; import org.teavm.backend.wasm.debug.DebugLines;
import org.teavm.backend.wasm.debug.DebugVariables; import org.teavm.backend.wasm.debug.DebugVariables;
import org.teavm.backend.wasm.generate.DwarfClassGenerator; import org.teavm.backend.wasm.generate.DwarfClassGenerator;
import org.teavm.backend.wasm.generate.DwarfFunctionGenerator;
import org.teavm.backend.wasm.generate.DwarfGenerator; import org.teavm.backend.wasm.generate.DwarfGenerator;
import org.teavm.backend.wasm.model.WasmCustomSection; import org.teavm.backend.wasm.model.WasmCustomSection;
import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.backend.wasm.model.WasmFunction;
@ -58,7 +57,7 @@ public class WasmBinaryRenderer {
private Map<String, Integer> functionIndexes = new HashMap<>(); private Map<String, Integer> functionIndexes = new HashMap<>();
private boolean obfuscated; private boolean obfuscated;
private DwarfGenerator dwarfGenerator; private DwarfGenerator dwarfGenerator;
private DwarfFunctionGenerator dwarfFunctionGen; private DwarfClassGenerator dwarfClassGen;
private DebugLines debugLines; private DebugLines debugLines;
private DebugVariables debugVariables; private DebugVariables debugVariables;
private WasmBinaryStatsCollector statsCollector; private WasmBinaryStatsCollector statsCollector;
@ -70,7 +69,7 @@ public class WasmBinaryRenderer {
this.version = version; this.version = version;
this.obfuscated = obfuscated; this.obfuscated = obfuscated;
this.dwarfGenerator = dwarfGenerator; this.dwarfGenerator = dwarfGenerator;
dwarfFunctionGen = dwarfClassGen != null ? new DwarfFunctionGenerator(dwarfClassGen, dwarfGenerator) : null; this.dwarfClassGen = dwarfClassGen;
this.debugLines = debugLines; this.debugLines = debugLines;
this.debugVariables = debugVariables; this.debugVariables = debugVariables;
this.statsCollector = statsCollector; this.statsCollector = statsCollector;
@ -300,8 +299,10 @@ public class WasmBinaryRenderer {
private byte[] renderFunction(WasmFunction function, int offset) { private byte[] renderFunction(WasmFunction function, int offset) {
var code = new WasmBinaryWriter(); var code = new WasmBinaryWriter();
if (dwarfFunctionGen != null) { var dwarfSubprogram = dwarfClassGen != null ? dwarfClassGen.getSubprogram(function.getName()) : null;
dwarfFunctionGen.begin(function, offset); if (dwarfSubprogram != null) {
dwarfSubprogram.startOffset = offset - 4;
dwarfSubprogram.function = function;
} }
if (debugLines != null && function.getJavaMethod() != null) { if (debugLines != null && function.getJavaMethod() != null) {
debugLines.start(function.getJavaMethod()); debugLines.start(function.getJavaMethod());
@ -343,8 +344,8 @@ public class WasmBinaryRenderer {
code.writeByte(0x0B); code.writeByte(0x0B);
if (dwarfFunctionGen != null) { if (dwarfSubprogram != null) {
dwarfFunctionGen.end(code.getPosition()); dwarfSubprogram.endOffset = code.getPosition() + offset;
} }
if (debugVariables != null) { if (debugVariables != null) {
writeDebugVariables(function, offset, code.getPosition()); writeDebugVariables(function, offset, code.getPosition());