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_UTF;
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_LOCATION;
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_DATA2;
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_STRP;
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_NAMESPACE;
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_VARIABLE;
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.DwarfInfoWriter;
import org.teavm.backend.wasm.dwarf.DwarfPlaceholder;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.PrimitiveType;
import org.teavm.model.ValueType;
@ -65,7 +63,6 @@ public class DwarfClassGenerator {
private DwarfAbbreviation nsAbbrev;
private DwarfAbbreviation classTypeAbbrev;
private DwarfAbbreviation inheritanceAbbrev;
private DwarfAbbreviation methodAbbrev;
private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length];
private DwarfPlaceholder unspecifiedType;
private DwarfAbbreviation baseTypeAbbrev;
@ -73,10 +70,12 @@ public class DwarfClassGenerator {
private DwarfAbbreviation variableAbbrev;
private List<Runnable> postponedWrites = new ArrayList<>();
private ClassType classClass;
private DwarfFunctionGenerator functionGen;
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
this.writer = writer;
this.strings = strings;
functionGen = new DwarfFunctionGenerator(this, writer, strings);
}
public void flushTypes() {
@ -117,16 +116,6 @@ public class DwarfClassGenerator {
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() {
if (nsAbbrev == null) {
nsAbbrev = writer.abbreviation(DW_TAG_NAMESPACE, true, data -> {
@ -391,18 +380,19 @@ public class DwarfClassGenerator {
public final String name;
public boolean isStatic;
public final MethodDescriptor descriptor;
public final DwarfPlaceholder ref;
public int startOffset;
public int endOffset;
public WasmFunction function;
private Subprogram(String name, MethodDescriptor descriptor) {
this.name = name;
this.descriptor = descriptor;
ref = writer.placeholder(4);
}
private void write() {
writer.mark(ref).tag(getMethodAbbrev());
writer.writeInt(strings.stringRef(name));
writer.emptyTag();
if (function != null) {
functionGen.writeContent(this);
}
}
}
}

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_LOW_PC;
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_FORM_ADDR;
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_VARIABLE;
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.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.model.WasmFunction;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
public class DwarfFunctionGenerator {
private DwarfClassGenerator classGen;
private DwarfGenerator generator;
private WasmFunction function;
private int offset;
private Marker endProgramMarker;
private DwarfInfoWriter writer;
private DwarfStrings strings;
private DwarfAbbreviation methodAbbrev;
private DwarfAbbreviation functionAbbrev;
private DwarfAbbreviation parameterAbbrev;
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.generator = generator;
this.writer = writer;
this.strings = strings;
}
public void begin(WasmFunction function, int offset) {
if (function.getName() == null) {
public void writeContent(DwarfClassGenerator.Subprogram subprogram) {
if (subprogram.function.getName() == null) {
return;
}
subprogram = classGen.getSubprogram(function.getName());
var writer = generator.getInfoWriter();
var strings = generator.strings;
writer.tag(subprogram != null ? getMethodAbbrev() : getFunctionAbbrev());
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);
writer.tag(getMethodAbbrev());
writer.writeInt(strings.stringRef(subprogram.name));
writer.writeInt(subprogram.startOffset);
writer.writeInt(subprogram.endOffset);
this.function = function;
this.offset = offset;
writeLocals(subprogram);
writeLocals();
writer.emptyTag();
}
private void writeLocals() {
if (subprogram == null) {
return;
}
private void writeLocals(DwarfClassGenerator.Subprogram subprogram) {
var descriptor = subprogram.descriptor;
if (descriptor == null) {
return;
}
var writer = generator.getInfoWriter();
var strings = generator.strings;
var function = subprogram.function;
var offset = subprogram.isStatic ? 0 : 1;
int count = Math.min(function.getLocalVariables().size() - offset, descriptor.parameterCount());
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() {
if (methodAbbrev == null) {
methodAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DW_AT_SPECIFICATION).writeLEB(DW_FORM_REF4);
methodAbbrev = writer.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);
});
@ -154,20 +117,9 @@ public class DwarfFunctionGenerator {
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() {
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_TYPE).writeLEB(DW_FORM_REF4);
data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC);
@ -178,7 +130,7 @@ public class DwarfFunctionGenerator {
private DwarfAbbreviation getVariableAbbrev() {
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_TYPE).writeLEB(DW_FORM_REF4);
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.DebugVariables;
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.model.WasmCustomSection;
import org.teavm.backend.wasm.model.WasmFunction;
@ -58,7 +57,7 @@ public class WasmBinaryRenderer {
private Map<String, Integer> functionIndexes = new HashMap<>();
private boolean obfuscated;
private DwarfGenerator dwarfGenerator;
private DwarfFunctionGenerator dwarfFunctionGen;
private DwarfClassGenerator dwarfClassGen;
private DebugLines debugLines;
private DebugVariables debugVariables;
private WasmBinaryStatsCollector statsCollector;
@ -70,7 +69,7 @@ public class WasmBinaryRenderer {
this.version = version;
this.obfuscated = obfuscated;
this.dwarfGenerator = dwarfGenerator;
dwarfFunctionGen = dwarfClassGen != null ? new DwarfFunctionGenerator(dwarfClassGen, dwarfGenerator) : null;
this.dwarfClassGen = dwarfClassGen;
this.debugLines = debugLines;
this.debugVariables = debugVariables;
this.statsCollector = statsCollector;
@ -300,8 +299,10 @@ public class WasmBinaryRenderer {
private byte[] renderFunction(WasmFunction function, int offset) {
var code = new WasmBinaryWriter();
if (dwarfFunctionGen != null) {
dwarfFunctionGen.begin(function, offset);
var dwarfSubprogram = dwarfClassGen != null ? dwarfClassGen.getSubprogram(function.getName()) : null;
if (dwarfSubprogram != null) {
dwarfSubprogram.startOffset = offset - 4;
dwarfSubprogram.function = function;
}
if (debugLines != null && function.getJavaMethod() != null) {
debugLines.start(function.getJavaMethod());
@ -343,8 +344,8 @@ public class WasmBinaryRenderer {
code.writeByte(0x0B);
if (dwarfFunctionGen != null) {
dwarfFunctionGen.end(code.getPosition());
if (dwarfSubprogram != null) {
dwarfSubprogram.endOffset = code.getPosition() + offset;
}
if (debugVariables != null) {
writeDebugVariables(function, offset, code.getPosition());