Skip to content

Commit 5c92d36

Browse files
committed
Add dwarf info for nested inlined subroutines
1 parent 210f14d commit 5c92d36

File tree

1 file changed

+80
-11
lines changed

1 file changed

+80
-11
lines changed

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java

Lines changed: 80 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828

2929
import com.oracle.objectfile.LayoutDecision;
3030
import com.oracle.objectfile.debugentry.ClassEntry;
31+
import com.oracle.objectfile.debugentry.FileEntry;
3132
import com.oracle.objectfile.debugentry.PrimaryEntry;
3233
import com.oracle.objectfile.debugentry.Range;
3334
import org.graalvm.compiler.debug.DebugContext;
3435

36+
import java.util.HashMap;
3537
import java.util.LinkedList;
3638

3739
import static com.oracle.objectfile.elf.dwarf.DwarfDebugInfo.DW_ABBREV_CODE_compile_unit_stmt_list;
@@ -124,6 +126,11 @@ public void createContent() {
124126

125127
/* CUs for normal methods */
126128
for (ClassEntry classEntry : getPrimaryClasses()) {
129+
/*
130+
* Save the offset of this file's CU so it can be used when writing the aranges section
131+
* and inlined_subroutines.
132+
*/
133+
classEntry.setCUIndex(pos);
127134
int lengthPos = pos;
128135
pos = writeCUHeader(buffer, pos);
129136
assert pos == lengthPos + DW_DIE_HEADER_SIZE;
@@ -135,6 +142,11 @@ public void createContent() {
135142
/* CUs for deopt targets */
136143
for (ClassEntry classEntry : getPrimaryClasses()) {
137144
if (classEntry.includesDeoptTarget()) {
145+
/*
146+
* Save the offset of this file's CU so it can be used when writing the aranges
147+
* section and inlined_subroutines.
148+
*/
149+
classEntry.setDeoptCUIndex(pos);
138150
int lengthPos = pos;
139151
pos = writeCUHeader(buffer, pos);
140152
assert pos == lengthPos + DW_DIE_HEADER_SIZE;
@@ -160,10 +172,6 @@ public void writeContent(DebugContext context) {
160172
log(context, " [0x%08x] size = 0x%08x", pos, size);
161173
/* write CUs for normal methods */
162174
for (ClassEntry classEntry : getPrimaryClasses()) {
163-
/*
164-
* Save the offset of this file's CU so it can be used when writing the aranges section.
165-
*/
166-
classEntry.setCUIndex(pos);
167175
int lengthPos = pos;
168176
pos = writeCUHeader(buffer, pos);
169177
log(context, " [0x%08x] Compilation Unit", pos, size);
@@ -177,11 +185,6 @@ public void writeContent(DebugContext context) {
177185
/* write CUs for deopt targets */
178186
for (ClassEntry classEntry : getPrimaryClasses()) {
179187
if (classEntry.includesDeoptTarget()) {
180-
/*
181-
* Save the offset of this file's CU so it can be used when writing the aranges
182-
* section.
183-
*/
184-
classEntry.setDeoptCUIndex(pos);
185188
int lengthPos = pos;
186189
pos = writeCUHeader(buffer, pos);
187190
log(context, " [0x%08x] Compilation Unit (deopt targets)", pos, size);
@@ -261,6 +264,7 @@ private static int findHi(LinkedList<PrimaryEntry> classPrimaryEntries, boolean
261264
private int writeCU(DebugContext context, ClassEntry classEntry, boolean isDeoptTargetCU, byte[] buffer, int p) {
262265
int pos = p;
263266
LinkedList<PrimaryEntry> classPrimaryEntries = classEntry.getPrimaryEntries();
267+
assert !classPrimaryEntries.isEmpty();
264268
int lineIndex = classEntry.getLineIndex();
265269
int abbrevCode = (lineIndex >= 0 ? DW_ABBREV_CODE_compile_unit_stmt_list : DW_ABBREV_CODE_compile_unit_no_stmt_list);
266270
log(context, " [0x%08x] <0> Abbrev Number %d", pos, abbrevCode);
@@ -282,10 +286,75 @@ private int writeCU(DebugContext context, ClassEntry classEntry, boolean isDeopt
282286
log(context, " [0x%08x] stmt_list 0x%08x", pos, lineIndex);
283287
pos = writeAttrData4(lineIndex, buffer, pos);
284288
}
289+
290+
/* Keep a map of method names to the corresponding position of their subprogram entry. */
291+
HashMap<String, Integer> primaryMap = new HashMap<>();
292+
/* The primary file entry should always be first in the local files list. */
293+
assert classEntry.localFilesIdx(classEntry.getFileEntry()) == 1;
294+
285295
for (PrimaryEntry primaryEntry : classPrimaryEntries) {
286296
Range range = primaryEntry.getPrimary();
287-
if (isDeoptTargetCU == range.isDeoptTarget()) {
288-
pos = writePrimary(context, range, false, false, 1, buffer, pos);
297+
if (isDeoptTargetCU != range.isDeoptTarget()) {
298+
continue;
299+
}
300+
primaryMap.put(range.getFullMethodName(), pos);
301+
boolean withChildren = false;
302+
/* Go through the subranges and generate abstract debug entries for inlined methods. */
303+
for (Range subrange : primaryEntry.getSubranges()) {
304+
if (!subrange.isInlined()) {
305+
continue;
306+
}
307+
withChildren = true;
308+
Integer subprogramPos = primaryMap.get(subrange.getFullMethodName());
309+
if (subprogramPos == null) {
310+
subprogramPos = pos;
311+
primaryMap.put(subrange.getFullMethodName(), subprogramPos);
312+
FileEntry subFileEntry = primaryEntry.getSubrangeFileEntry(subrange);
313+
assert subFileEntry != null;
314+
if (subFileEntry == null) {
315+
continue;
316+
}
317+
Integer fileIndex = classEntry.localFilesIdx(subFileEntry);
318+
assert fileIndex != null;
319+
pos = writePrimary(context, subrange, true, false, fileIndex, buffer, pos);
320+
}
321+
}
322+
pos = writePrimary(context, range, false, withChildren, 1, buffer, pos);
323+
if (withChildren) {
324+
int depth = 0;
325+
/* Go through the subranges and generate concrete debug entries for inlined methods. */
326+
for (Range subrange : primaryEntry.getSubranges()) {
327+
if (!subrange.isInlined()) {
328+
continue;
329+
}
330+
Integer subprogramPos = primaryMap.get(subrange.getFullMethodName());
331+
assert subprogramPos != null;
332+
final Range callerSubrange = subrange.getCaller();
333+
assert callerSubrange != null;
334+
Integer fileIndex;
335+
if (callerSubrange == range) {
336+
fileIndex = 1;
337+
} else {
338+
FileEntry subFileEntry = primaryEntry.getSubrangeFileEntry(callerSubrange);
339+
assert subFileEntry != null;
340+
fileIndex = classEntry.localFilesIdx(subFileEntry);
341+
assert fileIndex != null;
342+
}
343+
int previousPos = pos;
344+
pos = writeInlineSubroutine(context, subrange, buffer, pos, subprogramPos - classEntry.getCUIndex(), depth, fileIndex);
345+
if (subrange.withChildren()) {
346+
if (previousPos != pos) {
347+
depth++;
348+
}
349+
} else {
350+
while (depth > 0) {
351+
pos = writeAttrNull(buffer, pos);
352+
depth--;
353+
}
354+
}
355+
}
356+
pos = writeAttrNull(buffer, pos);
357+
assert depth == 0 : depth;
289358
}
290359
}
291360
/*

0 commit comments

Comments
 (0)