Skip to content

Commit f07c03f

Browse files
committed
[GR-38416] [GR-38648] Implement debug location info.
PullRequest: graal/11739
2 parents 672df39 + d47313e commit f07c03f

File tree

20 files changed

+3601
-896
lines changed

20 files changed

+3601
-896
lines changed

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,12 +838,12 @@ def build_debug_test(extra_args):
838838

839839
build_debug_test(['-H:+SpawnIsolates'])
840840
if mx.get_os() == 'linux' and not build_only:
841-
os.environ.update({'debuginfotest.isolates' : 'yes'})
841+
os.environ.update({'debuginfotest_isolates' : 'yes'})
842842
mx.run([os.environ.get('GDB_BIN', 'gdb'), '-ex', 'python "ISOLATES=True"', '-x', join(parent, 'mx.substratevm/testhello.py'), join(path, 'hello.hello')])
843843

844844
build_debug_test(['-H:-SpawnIsolates'])
845845
if mx.get_os() == 'linux' and not build_only:
846-
os.environ.update({'debuginfotest.isolates' : 'no'})
846+
os.environ.update({'debuginfotest_isolates' : 'no'})
847847
mx.run([os.environ.get('GDB_BIN', 'gdb'), '-ex', 'python "ISOLATES=False"', '-x', join(parent, 'mx.substratevm/testhello.py'), join(path, 'hello.hello')])
848848

849849
def _javac_image(native_image, path, args=None):

substratevm/mx.substratevm/suite.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,9 @@
795795
"jdk.internal.ref",
796796
"sun.nio.ch",
797797
],
798+
"jdk.internal.vm.ci" : [
799+
"jdk.vm.ci.code",
800+
],
798801
},
799802
"checkstyle" : "com.oracle.svm.hosted",
800803
"javaCompliance": "11+",

substratevm/mx.substratevm/testhello.py

Lines changed: 238 additions & 106 deletions
Large diffs are not rendered by default.

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/ClassEntry.java

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFieldInfo;
3838
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFrameSizeChange;
3939
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugInstanceTypeInfo;
40+
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocalInfo;
4041
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugMethodInfo;
4142
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugRangeInfo;
4243
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo;
@@ -285,32 +286,23 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa
285286
String methodName = debugMethodInfo.name();
286287
String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.valueType());
287288
int modifiers = debugMethodInfo.modifiers();
288-
List<String> paramTypes = debugMethodInfo.paramTypes();
289-
List<String> paramNames = debugMethodInfo.paramNames();
290-
assert paramTypes.size() == paramNames.size();
291-
int paramCount = paramTypes.size();
289+
DebugLocalInfo[] paramInfos = debugMethodInfo.getParamInfo();
290+
DebugLocalInfo thisParam = debugMethodInfo.getThisParamInfo();
291+
int paramCount = paramInfos.length;
292292
debugContext.log("typename %s adding %s method %s %s(%s)\n",
293-
typeName, memberModifiers(modifiers), resultTypeName, methodName, formatParams(paramTypes, paramNames));
293+
typeName, memberModifiers(modifiers), resultTypeName, methodName, formatParams(paramInfos));
294294
TypeEntry resultType = debugInfoBase.lookupTypeEntry(resultTypeName);
295-
TypeEntry[] paramTypeArray = null;
296-
String[] paramNameArray = null;
297-
if (paramCount != 0) {
298-
paramTypeArray = new TypeEntry[paramCount];
299-
paramNameArray = new String[paramCount];
300-
int idx = 0;
301-
for (String paramTypeName : paramTypes) {
302-
TypeEntry paramType = debugInfoBase.lookupTypeEntry(TypeEntry.canonicalize(paramTypeName));
303-
paramTypeArray[idx++] = paramType;
304-
}
305-
paramNameArray = paramNames.toArray(paramNameArray);
295+
TypeEntry[] typeEntries = new TypeEntry[paramCount];
296+
for (int i = 0; i < paramCount; i++) {
297+
typeEntries[i] = debugInfoBase.lookupTypeEntry(TypeEntry.canonicalize(paramInfos[i].typeName()));
306298
}
307299
/*
308300
* n.b. the method file may differ from the owning class file when the method is a
309301
* substitution
310302
*/
311303
FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(debugMethodInfo);
312304
MethodEntry methodEntry = new MethodEntry(debugInfoBase, debugMethodInfo, methodFileEntry, methodName,
313-
this, resultType, paramTypeArray, paramNameArray);
305+
this, resultType, typeEntries, paramInfos, thisParam);
314306
indexMethodEntry(methodEntry);
315307

316308
return methodEntry;
@@ -326,21 +318,18 @@ protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debug
326318
return fieldEntry;
327319
}
328320

329-
private static String formatParams(List<String> paramTypes, List<String> paramNames) {
330-
if (paramNames.size() == 0) {
321+
private static String formatParams(DebugLocalInfo[] paramInfo) {
322+
if (paramInfo.length == 0) {
331323
return "";
332324
}
333325
StringBuilder builder = new StringBuilder();
334-
String separator = "";
335-
for (int i = 0; i < paramNames.size(); i++) {
336-
builder.append(separator);
337-
builder.append(paramTypes.get(i));
338-
String paramName = paramNames.get(i);
339-
if (paramName.length() > 0) {
340-
builder.append(' ');
341-
builder.append(paramName);
326+
for (int i = 0; i < paramInfo.length; i++) {
327+
if (i > 0) {
328+
builder.append(", ");
342329
}
343-
separator = ", ";
330+
builder.append(paramInfo[i].typeName());
331+
builder.append(' ');
332+
builder.append(paramInfo[i].name());
344333
}
345334

346335
return builder.toString();

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import org.graalvm.compiler.debug.DebugContext;
4040

4141
import com.oracle.objectfile.debuginfo.DebugInfoProvider;
42+
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocationInfo;
43+
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocalValueInfo;
4244
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
4345
import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo;
4446

@@ -255,8 +257,8 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
255257
* Record all subranges even if they have no line or file so we at least get a symbol
256258
* for them and don't see a break in the address range.
257259
*/
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));
260262
}));
261263

262264
debugInfoProvider.dataInfoProvider().forEach(debugDataInfo -> debugDataInfo.debugContext((debugContext) -> {
@@ -338,45 +340,55 @@ ClassEntry lookupClassEntry(String typeName) {
338340
}
339341

340342
/**
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.
343345
*
344-
* @param lineInfo
346+
* @param locationInfo
345347
* @param primaryRange
346348
* @param classEntry
347349
* @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
349351
* primaryRange
350352
*/
351353
@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) {
356355
/*
357356
* We still insert subranges for the primary method but they don't actually count as inline.
358357
* we only need a range so that subranges for inline code can refer to the top level line
359-
* number
358+
* number.
360359
*/
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();
372378
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);
375381
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);
379390
}
391+
subRange.setLocalValueInfo(localValueInfos);
380392
return subRange;
381393
}
382394

0 commit comments

Comments
 (0)