|
39 | 39 | import org.graalvm.compiler.debug.DebugContext; |
40 | 40 |
|
41 | 41 | import com.oracle.objectfile.debuginfo.DebugInfoProvider; |
| 42 | +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocationInfo; |
| 43 | +import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocalValueInfo; |
42 | 44 | import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind; |
43 | 45 | import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo; |
44 | 46 |
|
@@ -255,8 +257,8 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) { |
255 | 257 | * Record all subranges even if they have no line or file so we at least get a symbol |
256 | 258 | * for them and don't see a break in the address range. |
257 | 259 | */ |
258 | | - debugCodeInfo.lineInfoProvider().forEach(debugLineInfo -> recursivelyAddSubRanges(debugLineInfo, primaryRange, classEntry, debugContext)); |
259 | | - primaryRange.mergeSubranges(debugContext); |
| 260 | + HashMap<DebugLocationInfo, Range> subRangeIndex = new HashMap<>(); |
| 261 | + debugCodeInfo.locationInfoProvider().forEach(debugLocationInfo -> addSubrange(debugLocationInfo, primaryRange, classEntry, subRangeIndex, debugContext)); |
260 | 262 | })); |
261 | 263 |
|
262 | 264 | debugInfoProvider.dataInfoProvider().forEach(debugDataInfo -> debugDataInfo.debugContext((debugContext) -> { |
@@ -338,45 +340,55 @@ ClassEntry lookupClassEntry(String typeName) { |
338 | 340 | } |
339 | 341 |
|
340 | 342 | /** |
341 | | - * Recursively creates subranges based on DebugLineInfo including, and appropriately linking, |
342 | | - * nested inline subranges. |
| 343 | + * Recursively creates subranges based on DebugLocationInfo including, and appropriately |
| 344 | + * linking, nested inline subranges. |
343 | 345 | * |
344 | | - * @param lineInfo |
| 346 | + * @param locationInfo |
345 | 347 | * @param primaryRange |
346 | 348 | * @param classEntry |
347 | 349 | * @param debugContext |
348 | | - * @return the subrange for {@code lineInfo} linked with all its caller subranges up to the |
| 350 | + * @return the subrange for {@code locationInfo} linked with all its caller subranges up to the |
349 | 351 | * primaryRange |
350 | 352 | */ |
351 | 353 | @SuppressWarnings("try") |
352 | | - private Range recursivelyAddSubRanges(DebugInfoProvider.DebugLineInfo lineInfo, Range primaryRange, ClassEntry classEntry, DebugContext debugContext) { |
353 | | - if (lineInfo == null) { |
354 | | - return primaryRange; |
355 | | - } |
| 354 | + private Range addSubrange(DebugLocationInfo locationInfo, Range primaryRange, ClassEntry classEntry, HashMap<DebugLocationInfo, Range> subRangeIndex, DebugContext debugContext) { |
356 | 355 | /* |
357 | 356 | * We still insert subranges for the primary method but they don't actually count as inline. |
358 | 357 | * we only need a range so that subranges for inline code can refer to the top level line |
359 | | - * number |
| 358 | + * number. |
360 | 359 | */ |
361 | | - boolean isInline = lineInfo.getCaller() != null; |
362 | | - assert (isInline || (lineInfo.name().equals(primaryRange.getMethodName()) && TypeEntry.canonicalize(lineInfo.ownerType().toJavaName()).equals(primaryRange.getClassName()))); |
363 | | - |
364 | | - Range caller = recursivelyAddSubRanges(lineInfo.getCaller(), primaryRange, classEntry, debugContext); |
365 | | - final String fileName = lineInfo.fileName(); |
366 | | - final Path filePath = lineInfo.filePath(); |
367 | | - final ResolvedJavaType ownerType = lineInfo.ownerType(); |
368 | | - final String methodName = lineInfo.name(); |
369 | | - final int lo = primaryRange.getLo() + lineInfo.addressLo(); |
370 | | - final int hi = primaryRange.getLo() + lineInfo.addressHi(); |
371 | | - final int line = lineInfo.line(); |
| 360 | + DebugLocationInfo callerLocationInfo = locationInfo.getCaller(); |
| 361 | + boolean isTopLevel = callerLocationInfo == null; |
| 362 | + assert (!isTopLevel || (locationInfo.name().equals(primaryRange.getMethodName()) && |
| 363 | + TypeEntry.canonicalize(locationInfo.ownerType().toJavaName()).equals(primaryRange.getClassName()))); |
| 364 | + Range caller = (isTopLevel ? primaryRange : subRangeIndex.get(callerLocationInfo)); |
| 365 | + // the frame tree is walked topdown so inline ranges should always have a caller range |
| 366 | + assert caller != null; |
| 367 | + |
| 368 | + final String fileName = locationInfo.fileName(); |
| 369 | + final Path filePath = locationInfo.filePath(); |
| 370 | + final String fullPath = (filePath == null ? "" : filePath.toString() + "/") + fileName; |
| 371 | + final ResolvedJavaType ownerType = locationInfo.ownerType(); |
| 372 | + final String methodName = locationInfo.name(); |
| 373 | + final int loOff = locationInfo.addressLo(); |
| 374 | + final int hiOff = locationInfo.addressHi() - 1; |
| 375 | + final int lo = primaryRange.getLo() + locationInfo.addressLo(); |
| 376 | + final int hi = primaryRange.getLo() + locationInfo.addressHi(); |
| 377 | + final int line = locationInfo.line(); |
372 | 378 | ClassEntry subRangeClassEntry = ensureClassEntry(ownerType); |
373 | | - MethodEntry subRangeMethodEntry = subRangeClassEntry.ensureMethodEntryForDebugRangeInfo(lineInfo, this, debugContext); |
374 | | - Range subRange = new Range(stringTable, subRangeMethodEntry, lo, hi, line, primaryRange, isInline, caller); |
| 379 | + MethodEntry subRangeMethodEntry = subRangeClassEntry.ensureMethodEntryForDebugRangeInfo(locationInfo, this, debugContext); |
| 380 | + Range subRange = new Range(stringTable, subRangeMethodEntry, lo, hi, line, primaryRange, isTopLevel, caller); |
375 | 381 | classEntry.indexSubRange(subRange); |
376 | | - try (DebugContext.Scope s = debugContext.scope("Subranges")) { |
377 | | - debugContext.log(DebugContext.DETAILED_LEVEL, "SubRange %s.%s %s %s:%d 0x%x, 0x%x]", |
378 | | - ownerType.toJavaName(), methodName, filePath, fileName, line, lo, hi); |
| 382 | + subRangeIndex.put(locationInfo, subRange); |
| 383 | + debugContext.log(DebugContext.DETAILED_LEVEL, "SubRange %s.%s %d %s:%d [0x%x, 0x%x] (%d, %d)", |
| 384 | + ownerType.toJavaName(), methodName, subRange.getDepth(), fullPath, line, lo, hi, loOff, hiOff); |
| 385 | + assert (callerLocationInfo == null || (callerLocationInfo.addressLo() <= loOff && callerLocationInfo.addressHi() >= hiOff)) : "parent range should enclose subrange!"; |
| 386 | + DebugLocalValueInfo[] localValueInfos = locationInfo.getLocalValueInfo(); |
| 387 | + for (int i = 0; i < localValueInfos.length; i++) { |
| 388 | + DebugLocalValueInfo localValueInfo = localValueInfos[i]; |
| 389 | + debugContext.log(DebugContext.DETAILED_LEVEL, " locals[%d] %s:%s = %s", localValueInfo.slot(), localValueInfo.name(), localValueInfo.typeName(), localValueInfo); |
379 | 390 | } |
| 391 | + subRange.setLocalValueInfo(localValueInfos); |
380 | 392 | return subRange; |
381 | 393 | } |
382 | 394 |
|
|
0 commit comments