2828
2929import com .oracle .objectfile .LayoutDecision ;
3030import com .oracle .objectfile .debugentry .ClassEntry ;
31+ import com .oracle .objectfile .debugentry .FileEntry ;
3132import com .oracle .objectfile .debugentry .PrimaryEntry ;
3233import com .oracle .objectfile .debugentry .Range ;
3334import org .graalvm .compiler .debug .DebugContext ;
3435
36+ import java .util .HashMap ;
3537import java .util .LinkedList ;
3638
3739import 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