Skip to content

Commit 8b38a08

Browse files
committed
[GR-39018] Debug id cleanup #4627.
PullRequest: graal/11916
2 parents f7d2d8e + f1b32e7 commit 8b38a08

File tree

13 files changed

+396
-262
lines changed

13 files changed

+396
-262
lines changed

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugArrayTypeInfo;
3030
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo;
3131
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
32+
import jdk.vm.ci.meta.ResolvedJavaType;
3233
import org.graalvm.compiler.debug.DebugContext;
3334

3435
public class ArrayTypeEntry extends StructureTypeEntry {
@@ -48,13 +49,13 @@ public DebugTypeKind typeKind() {
4849
@Override
4950
public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInfo, DebugContext debugContext) {
5051
DebugArrayTypeInfo debugArrayTypeInfo = (DebugArrayTypeInfo) debugTypeInfo;
51-
String elementTypeName = TypeEntry.canonicalize(debugArrayTypeInfo.elementType());
52-
this.elementType = debugInfoBase.lookupTypeEntry(elementTypeName);
52+
ResolvedJavaType eltType = debugArrayTypeInfo.elementType();
53+
this.elementType = debugInfoBase.lookupTypeEntry(eltType);
5354
this.baseSize = debugArrayTypeInfo.baseSize();
5455
this.lengthOffset = debugArrayTypeInfo.lengthOffset();
5556
/* Add details of fields and field types */
5657
debugArrayTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext));
57-
debugContext.log("typename %s element type %s base size %d length offset %d\n", typeName, elementTypeName, baseSize, lengthOffset);
58+
debugContext.log("typename %s element type %s base size %d length offset %d\n", typeName, this.elementType.getTypeName(), baseSize, lengthOffset);
5859
}
5960

6061
public TypeEntry getElementType() {

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

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import java.util.List;
3333
import java.util.Map;
3434

35+
import jdk.vm.ci.meta.ResolvedJavaMethod;
36+
import jdk.vm.ci.meta.ResolvedJavaType;
3537
import org.graalvm.compiler.debug.DebugContext;
3638

3739
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugFieldInfo;
@@ -64,9 +66,10 @@ public class ClassEntry extends StructureTypeEntry {
6466
*/
6567
protected List<MethodEntry> methods;
6668
/**
67-
* An index of all currently known methods keyed by the unique local symbol name of the method.
69+
* An index of all currently known methods keyed by the unique, associated, identifying
70+
* ResolvedJavaMethod.
6871
*/
69-
private Map<String, MethodEntry> methodsIndex;
72+
private Map<ResolvedJavaMethod, MethodEntry> methodsIndex;
7073
/**
7174
* A list recording details of all primary ranges included in this class sorted by ascending
7275
* address range.
@@ -127,18 +130,21 @@ public DebugTypeKind typeKind() {
127130

128131
@Override
129132
public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInfo, DebugContext debugContext) {
130-
assert TypeEntry.canonicalize(debugTypeInfo.typeName()).equals(typeName);
133+
assert debugTypeInfo.typeName().equals(typeName);
131134
DebugInstanceTypeInfo debugInstanceTypeInfo = (DebugInstanceTypeInfo) debugTypeInfo;
132135
/* Add details of super and interface classes */
133-
String superName = debugInstanceTypeInfo.superName();
134-
if (superName != null) {
135-
superName = TypeEntry.canonicalize(superName);
136+
ResolvedJavaType superType = debugInstanceTypeInfo.superClass();
137+
String superName;
138+
if (superType != null) {
139+
superName = superType.toJavaName();
140+
} else {
141+
superName = "";
136142
}
137143
debugContext.log("typename %s adding super %s\n", typeName, superName);
138-
if (superName != null) {
139-
this.superClass = debugInfoBase.lookupClassEntry(superName);
144+
if (superType != null) {
145+
this.superClass = debugInfoBase.lookupClassEntry(superType);
140146
}
141-
debugInstanceTypeInfo.interfaces().forEach(interfaceName -> processInterface(interfaceName, debugInfoBase, debugContext));
147+
debugInstanceTypeInfo.interfaces().forEach(interfaceType -> processInterface(interfaceType, debugInfoBase, debugContext));
142148
/* Add details of fields and field types */
143149
debugInstanceTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext));
144150
/* Add details of methods and method types */
@@ -177,11 +183,10 @@ public void indexSubRange(Range subrange) {
177183
}
178184
}
179185

180-
private void indexMethodEntry(MethodEntry methodEntry) {
181-
String methodName = methodEntry.getSymbolName();
182-
assert methodsIndex.get(methodName) == null : methodName;
186+
private void indexMethodEntry(MethodEntry methodEntry, ResolvedJavaMethod idMethod) {
187+
assert methodsIndex.get(idMethod) == null : methodEntry.getSymbolName();
183188
methods.add(methodEntry);
184-
methodsIndex.put(methodName, methodEntry);
189+
methodsIndex.put(idMethod, methodEntry);
185190
}
186191

187192
private void indexLocalFileEntry(FileEntry localFileEntry) {
@@ -273,9 +278,10 @@ public String getCachePath() {
273278
return "";
274279
}
275280

276-
private void processInterface(String interfaceName, DebugInfoBase debugInfoBase, DebugContext debugContext) {
281+
private void processInterface(ResolvedJavaType interfaceType, DebugInfoBase debugInfoBase, DebugContext debugContext) {
282+
String interfaceName = interfaceType.toJavaName();
277283
debugContext.log("typename %s adding interface %s\n", typeName, interfaceName);
278-
ClassEntry entry = debugInfoBase.lookupClassEntry(TypeEntry.canonicalize(interfaceName));
284+
ClassEntry entry = debugInfoBase.lookupClassEntry(interfaceType);
279285
assert entry instanceof InterfaceClassEntry;
280286
InterfaceClassEntry interfaceClassEntry = (InterfaceClassEntry) entry;
281287
interfaces.add(interfaceClassEntry);
@@ -284,26 +290,27 @@ private void processInterface(String interfaceName, DebugInfoBase debugInfoBase,
284290

285291
protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
286292
String methodName = debugMethodInfo.name();
287-
String resultTypeName = TypeEntry.canonicalize(debugMethodInfo.valueType());
293+
ResolvedJavaType resultType = debugMethodInfo.valueType();
294+
String resultTypeName = resultType.toJavaName();
288295
int modifiers = debugMethodInfo.modifiers();
289296
DebugLocalInfo[] paramInfos = debugMethodInfo.getParamInfo();
290297
DebugLocalInfo thisParam = debugMethodInfo.getThisParamInfo();
291298
int paramCount = paramInfos.length;
292299
debugContext.log("typename %s adding %s method %s %s(%s)\n",
293300
typeName, memberModifiers(modifiers), resultTypeName, methodName, formatParams(paramInfos));
294-
TypeEntry resultType = debugInfoBase.lookupTypeEntry(resultTypeName);
301+
TypeEntry resultTypeEntry = debugInfoBase.lookupTypeEntry(resultType);
295302
TypeEntry[] typeEntries = new TypeEntry[paramCount];
296303
for (int i = 0; i < paramCount; i++) {
297-
typeEntries[i] = debugInfoBase.lookupTypeEntry(TypeEntry.canonicalize(paramInfos[i].typeName()));
304+
typeEntries[i] = debugInfoBase.lookupTypeEntry(paramInfos[i].valueType());
298305
}
299306
/*
300307
* n.b. the method file may differ from the owning class file when the method is a
301308
* substitution
302309
*/
303310
FileEntry methodFileEntry = debugInfoBase.ensureFileEntry(debugMethodInfo);
304311
MethodEntry methodEntry = new MethodEntry(debugInfoBase, debugMethodInfo, methodFileEntry, methodName,
305-
this, resultType, typeEntries, paramInfos, thisParam);
306-
indexMethodEntry(methodEntry);
312+
this, resultTypeEntry, typeEntries, paramInfos, thisParam);
313+
indexMethodEntry(methodEntry, debugMethodInfo.idMethod());
307314

308315
return methodEntry;
309316
}
@@ -345,7 +352,7 @@ public ClassEntry getSuperClass() {
345352

346353
public MethodEntry ensureMethodEntryForDebugRangeInfo(DebugRangeInfo debugRangeInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
347354

348-
MethodEntry methodEntry = methodsIndex.get(debugRangeInfo.symbolNameForMethod());
355+
MethodEntry methodEntry = methodsIndex.get(debugRangeInfo.idMethod());
349356
if (methodEntry == null) {
350357
methodEntry = processMethod(debugRangeInfo, debugInfoBase, debugContext);
351358
} else {

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

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public abstract class DebugInfoBase {
7272
*
7373
* An alternative traversal option is
7474
*
75-
* 1) by top level class (String id)
75+
* 1) by top level class (unique ResolvedJavaType id)
7676
*
7777
* 2) by top level compiled method (primary Range) within a class ordered by ascending address
7878
*
@@ -83,6 +83,18 @@ public abstract class DebugInfoBase {
8383
* means we can treat each class as a compilation unit, allowing data common to all methods of
8484
* the class to be shared.
8585
*
86+
* Just as an aside, for full disclosure, this is not strictly the full story. Sometimes a class
87+
* can include speculatively optimized, compiled methods plus deopt fallback compiled variants
88+
* of those same methods. In such cases the normal and/or speculatively compiled methods occupy
89+
* one contiguous range and deopt methods occupy a separate higher range. The current
90+
* compilation strategy ensures that the union across all classes of the normal/speculative
91+
* ranges and the union across all classes of the deopt ranges lie in two distinct intervals
92+
* where the highest address in the first union is strictly less than the lowest address in the
93+
* second union. The implication is twofold. An address order traversal requires generating
94+
* details for classes, methods and non-deopt primary ranges before generating details for the
95+
* deopt primary ranges. The former details need to be generated in a distinct CU from deopt
96+
* method details.
97+
*
8698
* A third option appears to be to traverse via files, then top level class within file etc.
8799
* Unfortunately, files cannot be treated as the compilation unit. A file F may contain multiple
88100
* classes, say C1 and C2. There is no guarantee that methods for some other class C' in file F'
@@ -96,17 +108,22 @@ public abstract class DebugInfoBase {
96108
*/
97109
private List<TypeEntry> types = new ArrayList<>();
98110
/**
99-
* index of already seen classes.
111+
* Index of already seen classes keyed by the unique, associated, identifying ResolvedJavaType
112+
* or, in the single special case of the TypeEntry for the Java header structure, by key null.
100113
*/
101-
private Map<String, TypeEntry> typesIndex = new HashMap<>();
114+
private Map<ResolvedJavaType, TypeEntry> typesIndex = new HashMap<>();
102115
/**
103116
* List of class entries detailing class info for primary ranges.
104117
*/
105118
private List<ClassEntry> primaryClasses = new ArrayList<>();
106119
/**
107-
* index of already seen classes.
120+
* Index of already seen classes.
108121
*/
109122
private Map<ResolvedJavaType, ClassEntry> primaryClassesIndex = new HashMap<>();
123+
/**
124+
* Handle on class entry for java.lang.Object.
125+
*/
126+
private ClassEntry objectClass;
110127
/**
111128
* Index of files which contain primary or secondary ranges.
112129
*/
@@ -213,7 +230,8 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
213230

214231
/* Create all the types. */
215232
debugInfoProvider.typeInfoProvider().forEach(debugTypeInfo -> debugTypeInfo.debugContext((debugContext) -> {
216-
String typeName = TypeEntry.canonicalize(debugTypeInfo.typeName());
233+
ResolvedJavaType idType = debugTypeInfo.idType();
234+
String typeName = debugTypeInfo.typeName();
217235
typeName = stringTable.uniqueDebugString(typeName);
218236
DebugTypeKind typeKind = debugTypeInfo.typeKind();
219237
int byteSize = debugTypeInfo.size();
@@ -222,16 +240,17 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
222240
String fileName = debugTypeInfo.fileName();
223241
Path filePath = debugTypeInfo.filePath();
224242
Path cachePath = debugTypeInfo.cachePath();
225-
addTypeEntry(typeName, fileName, filePath, cachePath, byteSize, typeKind);
243+
addTypeEntry(idType, typeName, fileName, filePath, cachePath, byteSize, typeKind);
226244
}));
227245

228246
/* Now we can cross reference static and instance field details. */
229247
debugInfoProvider.typeInfoProvider().forEach(debugTypeInfo -> debugTypeInfo.debugContext((debugContext) -> {
230-
String typeName = TypeEntry.canonicalize(debugTypeInfo.typeName());
248+
ResolvedJavaType idType = debugTypeInfo.idType();
249+
String typeName = debugTypeInfo.typeName();
231250
DebugTypeKind typeKind = debugTypeInfo.typeKind();
232251

233252
debugContext.log(DebugContext.INFO_LEVEL, "Process %s type %s ", typeKind.toString(), typeName);
234-
TypeEntry typeEntry = lookupTypeEntry(typeName);
253+
TypeEntry typeEntry = lookupTypeEntry(idType);
235254
typeEntry.addDebugInfo(this, debugTypeInfo, debugContext);
236255
}));
237256

@@ -309,12 +328,15 @@ private TypeEntry createTypeEntry(String typeName, String fileName, Path filePat
309328
return typeEntry;
310329
}
311330

312-
private TypeEntry addTypeEntry(String typeName, String fileName, Path filePath, Path cachePath, int size, DebugTypeKind typeKind) {
313-
TypeEntry typeEntry = typesIndex.get(typeName);
331+
private TypeEntry addTypeEntry(ResolvedJavaType idType, String typeName, String fileName, Path filePath, Path cachePath, int size, DebugTypeKind typeKind) {
332+
TypeEntry typeEntry = typesIndex.get(idType);
314333
if (typeEntry == null) {
315334
typeEntry = createTypeEntry(typeName, fileName, filePath, cachePath, size, typeKind);
316335
types.add(typeEntry);
317-
typesIndex.put(typeName, typeEntry);
336+
typesIndex.put(idType, typeEntry);
337+
if (typeName.equals("java.lang.Object")) {
338+
objectClass = (ClassEntry) typeEntry;
339+
}
318340
} else {
319341
if (!(typeEntry.isClass())) {
320342
assert ((ClassEntry) typeEntry).getFileName().equals(fileName);
@@ -323,22 +345,26 @@ private TypeEntry addTypeEntry(String typeName, String fileName, Path filePath,
323345
return typeEntry;
324346
}
325347

326-
public TypeEntry lookupTypeEntry(String typeName) {
327-
TypeEntry typeEntry = typesIndex.get(typeName);
348+
public TypeEntry lookupTypeEntry(ResolvedJavaType type) {
349+
TypeEntry typeEntry = typesIndex.get(type);
328350
if (typeEntry == null) {
329-
throw new RuntimeException("type entry not found " + typeName);
351+
throw new RuntimeException("type entry not found " + type.getName());
330352
}
331353
return typeEntry;
332354
}
333355

334-
ClassEntry lookupClassEntry(String typeName) {
335-
TypeEntry typeEntry = typesIndex.get(typeName);
356+
ClassEntry lookupClassEntry(ResolvedJavaType type) {
357+
TypeEntry typeEntry = typesIndex.get(type);
336358
if (typeEntry == null || !(typeEntry.isClass())) {
337-
throw new RuntimeException("class entry not found " + typeName);
359+
throw new RuntimeException("class entry not found " + type.getName());
338360
}
339361
return (ClassEntry) typeEntry;
340362
}
341363

364+
public ClassEntry lookupObjectClass() {
365+
return objectClass;
366+
}
367+
342368
/**
343369
* Recursively creates subranges based on DebugLocationInfo including, and appropriately
344370
* linking, nested inline subranges.
@@ -360,7 +386,7 @@ private Range addSubrange(DebugLocationInfo locationInfo, Range primaryRange, Cl
360386
DebugLocationInfo callerLocationInfo = locationInfo.getCaller();
361387
boolean isTopLevel = callerLocationInfo == null;
362388
assert (!isTopLevel || (locationInfo.name().equals(primaryRange.getMethodName()) &&
363-
TypeEntry.canonicalize(locationInfo.ownerType().toJavaName()).equals(primaryRange.getClassName())));
389+
locationInfo.ownerType().toJavaName().equals(primaryRange.getClassName())));
364390
Range caller = (isTopLevel ? primaryRange : subRangeIndex.get(callerLocationInfo));
365391
// the frame tree is walked topdown so inline ranges should always have a caller range
366392
assert caller != null;
@@ -396,13 +422,13 @@ private ClassEntry ensureClassEntry(ResolvedJavaType type) {
396422
/* See if we already have an entry. */
397423
ClassEntry classEntry = primaryClassesIndex.get(type);
398424
if (classEntry == null) {
399-
TypeEntry typeEntry = typesIndex.get(TypeEntry.canonicalize(type.toJavaName()));
425+
TypeEntry typeEntry = typesIndex.get(type);
400426
assert (typeEntry != null && typeEntry.isClass());
401427
classEntry = (ClassEntry) typeEntry;
402428
primaryClasses.add(classEntry);
403429
primaryClassesIndex.put(type, classEntry);
404430
}
405-
assert (classEntry.getTypeName().equals(TypeEntry.canonicalize(type.toJavaName())));
431+
assert (classEntry.getTypeName().equals(type.toJavaName()));
406432
return classEntry;
407433
}
408434

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
package com.oracle.objectfile.debugentry;
2828

29-
import com.oracle.objectfile.debuginfo.DebugInfoProvider;
29+
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo;
3030
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugEnumTypeInfo;
3131
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
3232
import org.graalvm.compiler.debug.DebugContext;
@@ -42,7 +42,7 @@ public DebugTypeKind typeKind() {
4242
}
4343

4444
@Override
45-
public void addDebugInfo(DebugInfoBase debugInfoBase, DebugInfoProvider.DebugTypeInfo debugTypeInfo, DebugContext debugContext) {
45+
public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInfo, DebugContext debugContext) {
4646
assert debugTypeInfo instanceof DebugEnumTypeInfo;
4747
super.addDebugInfo(debugInfoBase, debugTypeInfo, debugContext);
4848
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public DebugTypeKind typeKind() {
4545

4646
@Override
4747
public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInfo, DebugContext debugContext) {
48-
assert TypeEntry.canonicalize(debugTypeInfo.typeName()).equals(typeName);
48+
assert debugTypeInfo.typeName().equals(typeName);
4949
DebugHeaderTypeInfo debugHeaderTypeInfo = (DebugHeaderTypeInfo) debugTypeInfo;
5050
debugHeaderTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext));
5151
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugMethodInfo;
3737

3838
import jdk.vm.ci.meta.JavaKind;
39+
import jdk.vm.ci.meta.ResolvedJavaType;
3940

4041
public class MethodEntry extends MemberEntry {
4142
private final TypeEntry[] paramTypes;
@@ -285,6 +286,11 @@ private static class DebugLocalInfoWrapper implements DebugLocalInfo {
285286
this.line = value.line();
286287
}
287288

289+
@Override
290+
public ResolvedJavaType valueType() {
291+
return value.valueType();
292+
}
293+
288294
@Override
289295
public String name() {
290296
return value.name();

0 commit comments

Comments
 (0)