Skip to content

Commit bc9748b

Browse files
Move hub processing in debug info to a separate type
1 parent cbe414a commit bc9748b

File tree

10 files changed

+154
-75
lines changed

10 files changed

+154
-75
lines changed

substratevm/debug/gdbpy/gdb-debughelpers.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class SVMUtil:
108108
string_type = gdb.lookup_type("java.lang.String")
109109
enum_type = gdb.lookup_type("java.lang.Enum")
110110
object_type = gdb.lookup_type("java.lang.Object")
111-
hub_type = gdb.lookup_type("java.lang.Class")
111+
hub_type = gdb.lookup_type("Encoded$Dynamic$Hub")
112112
null = gdb.Value(0).cast(object_type.pointer())
113113
classloader_type = gdb.lookup_type("java.lang.ClassLoader")
114114
wrapper_types = [gdb.lookup_type(f'java.lang.{x}') for x in
@@ -141,7 +141,7 @@ def get_uncompressed_type(cls, t: gdb.Type) -> gdb.Type:
141141
# compressed types only exist for java type which are either struct or union
142142
if t.code != gdb.TYPE_CODE_STRUCT and t.code != gdb.TYPE_CODE_UNION:
143143
return t
144-
result = cls.get_base_class(t) if cls.is_compressed(t) else t
144+
result = cls.get_base_class(t) if (cls.is_compressed(t) and t != cls.hub_type) else t
145145
trace(f'<SVMUtil> - get_uncompressed_type({t}) = {result}')
146146
return result
147147

@@ -177,7 +177,7 @@ def get_compressed_oop(cls, obj: gdb.Value) -> int:
177177
# recreate compressed oop from the object address
178178
# this reverses the uncompress expression from
179179
# com.oracle.objectfile.elf.dwarf.DwarfInfoSectionImpl#writeIndirectOopConversionExpression
180-
is_hub = cls.get_rtt(obj) == cls.hub_type
180+
is_hub = cls.get_basic_type(obj.type) == cls.hub_type
181181
compression_shift = cls.compression_shift
182182
num_reserved_bits = int.bit_count(cls.reserved_bits_mask)
183183
num_alignment_bits = int.bit_count(cls.object_alignment - 1)
@@ -205,6 +205,11 @@ def get_unqualified_type_name(cls, qualified_type_name: str) -> str:
205205

206206
@classmethod
207207
def is_compressed(cls, t: gdb.Type) -> bool:
208+
# for the hub type we always want handle it as compressed as there is no clear distinction in debug info for
209+
# the hub field, and it may always have an expression in the type's data_location attribute
210+
if cls.get_basic_type(t) == cls.hub_type:
211+
return True
212+
208213
type_name = cls.get_basic_type(t).name
209214
if type_name is None:
210215
# fallback to the GDB type printer for t
@@ -363,6 +368,9 @@ def get_classloader_namespace(cls, obj: gdb.Value) -> str:
363368
def get_rtt(cls, obj: gdb.Value) -> gdb.Type:
364369
static_type = cls.get_basic_type(obj.type)
365370

371+
if static_type == cls.hub_type:
372+
return cls.hub_type
373+
366374
# check for interfaces and cast them to Object to make the hub accessible
367375
if cls.get_uncompressed_type(cls.get_basic_type(obj.type)).code == gdb.TYPE_CODE_UNION:
368376
obj = cls.cast_to(obj, cls.object_type)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa
288288
}
289289

290290
@Override
291-
protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
292-
FieldEntry fieldEntry = super.addField(debugFieldInfo, debugInfoBase, debugContext);
291+
protected FieldEntry createField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
292+
FieldEntry fieldEntry = super.createField(debugFieldInfo, debugInfoBase, debugContext);
293293
return fieldEntry;
294294
}
295295

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

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocalValueInfo;
4747
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocationInfo;
4848
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
49-
import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo;
5049

5150
import jdk.graal.compiler.debug.DebugContext;
5251
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -135,6 +134,10 @@ public abstract class DebugInfoBase {
135134
* Handle on class entry for java.lang.Object.
136135
*/
137136
private ClassEntry objectClass;
137+
/**
138+
* The type entry for java.lang.Class.
139+
*/
140+
private ClassEntry classClass;
138141
/**
139142
* List of all top level compiled methods found in debug info. These ought to arrive via the
140143
* debug info API in ascending address range order.
@@ -202,11 +205,6 @@ public abstract class DebugInfoBase {
202205
*/
203206
private int compiledCodeMax;
204207

205-
/**
206-
* The type entry for java.lang.Class.
207-
*/
208-
private ClassEntry hubClassEntry;
209-
210208
@SuppressWarnings("this-escape")
211209
public DebugInfoBase(ByteOrder byteOrder) {
212210
this.byteOrder = byteOrder;
@@ -218,7 +216,6 @@ public DebugInfoBase(ByteOrder byteOrder) {
218216
this.pointerSize = 0;
219217
this.objectAlignment = 0;
220218
this.numAlignmentBits = 0;
221-
this.hubClassEntry = null;
222219
this.compiledCodeMax = 0;
223220
// create and index an empty dir with index 0.
224221
ensureDirEntry(EMPTY_PATH);
@@ -372,9 +369,6 @@ private TypeEntry createTypeEntry(String typeName, String fileName, Path filePat
372369
case INSTANCE: {
373370
FileEntry fileEntry = addFileEntry(fileName, filePath);
374371
typeEntry = new ClassEntry(typeName, fileEntry, size);
375-
if (typeEntry.getTypeName().equals(DwarfDebugInfo.HUB_TYPE_NAME)) {
376-
hubClassEntry = (ClassEntry) typeEntry;
377-
}
378372
break;
379373
}
380374
case INTERFACE: {
@@ -423,6 +417,9 @@ private TypeEntry addTypeEntry(ResolvedJavaType idType, String typeName, String
423417
if (idType == null) {
424418
headerType = (HeaderTypeEntry) typeEntry;
425419
}
420+
if (typeName.equals("java.lang.Class")) {
421+
classClass = (ClassEntry) typeEntry;
422+
}
426423
if (typeName.equals("java.lang.Object")) {
427424
objectClass = (ClassEntry) typeEntry;
428425
}
@@ -479,6 +476,12 @@ public ClassEntry lookupObjectClass() {
479476
return objectClass;
480477
}
481478

479+
public ClassEntry lookupClassClass() {
480+
// this should only be looked up after all types have been notified
481+
assert classClass != null;
482+
return classClass;
483+
}
484+
482485
private void addPrimaryRange(PrimaryRange primaryRange, DebugCodeInfo debugCodeInfo, ClassEntry classEntry) {
483486
CompiledMethodEntry compiledMethod = classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize());
484487
indexCompiledMethod(compiledMethod);
@@ -737,14 +740,6 @@ public String getCachePath() {
737740
return cachePath;
738741
}
739742

740-
public boolean isHubClassEntry(StructureTypeEntry typeEntry) {
741-
return typeEntry.getTypeName().equals(DwarfDebugInfo.HUB_TYPE_NAME);
742-
}
743-
744-
public ClassEntry getHubClassEntry() {
745-
return hubClassEntry;
746-
}
747-
748743
private static void collectFilesAndDirs(ClassEntry classEntry) {
749744
// track files and dirs we have already seen so that we only add them once
750745
EconomicSet<FileEntry> visitedFiles = EconomicSet.create();

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,16 @@
3434

3535
public class HeaderTypeEntry extends StructureTypeEntry {
3636

37+
FieldEntry hubField;
38+
3739
public HeaderTypeEntry(String typeName, int size) {
3840
super(typeName, size);
3941
}
4042

43+
public FieldEntry getHubField() {
44+
return hubField;
45+
}
46+
4147
@Override
4248
public DebugTypeKind typeKind() {
4349
return DebugTypeKind.HEADER;
@@ -49,5 +55,6 @@ public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInf
4955
assert debugTypeInfo.typeName().equals(typeName);
5056
DebugHeaderTypeInfo debugHeaderTypeInfo = (DebugHeaderTypeInfo) debugTypeInfo;
5157
debugHeaderTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext));
58+
hubField = createField(debugHeaderTypeInfo.hubField(), debugInfoBase, debugContext);
5259
}
5360
}

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ public int fieldCount() {
7575

7676
protected void processField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
7777
/* Delegate this so superclasses can override this and inspect the computed FieldEntry. */
78-
addField(debugFieldInfo, debugInfoBase, debugContext);
78+
FieldEntry fieldEntry = createField(debugFieldInfo, debugInfoBase, debugContext);
79+
fields.add(fieldEntry);
7980
}
8081

81-
protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
82+
protected FieldEntry createField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
8283
String fieldName = debugInfoBase.uniqueDebugString(debugFieldInfo.name());
8384
ResolvedJavaType valueType = debugFieldInfo.valueType();
8485
String valueTypeName = valueType.toJavaName();
@@ -96,9 +97,7 @@ protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debug
9697
* substitution
9798
*/
9899
FileEntry fileEntry = debugInfoBase.ensureFileEntry(debugFieldInfo);
99-
FieldEntry fieldEntry = new FieldEntry(fileEntry, fieldName, this, valueTypeEntry, fieldSize, fieldoffset, fieldIsEmbedded, fieldModifiers);
100-
fields.add(fieldEntry);
101-
return fieldEntry;
100+
return new FieldEntry(fileEntry, fieldName, this, valueTypeEntry, fieldSize, fieldoffset, fieldIsEmbedded, fieldModifiers);
102101
}
103102

104103
String memberModifiers(int modifiers) {

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ interface DebugPrimitiveTypeInfo extends DebugTypeInfo {
219219
interface DebugHeaderTypeInfo extends DebugTypeInfo {
220220

221221
Stream<DebugFieldInfo> fieldInfoProvider();
222+
223+
DebugFieldInfo hubField();
222224
}
223225

224226
interface DebugMemberInfo extends DebugFileInfo {

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

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -956,10 +956,11 @@ public int writeAbbrevs(DebugContext context, byte[] buffer, int p) {
956956
*
957957
* if address rebasing is not required then a data_location attribute on the layout type
958958
* will ensure that address tag bits are removed.
959+
*
960+
* The compressed layout is also used for representing the decode step for dynamic hubs.
961+
* I.e. this is also required for builds without isolates
959962
*/
960-
if (dwarfSections.useHeapBase()) {
961-
pos = writeCompressedLayoutAbbrev(context, buffer, pos);
962-
}
963+
pos = writeCompressedLayoutAbbrev(context, buffer, pos);
963964

964965
pos = writeParameterDeclarationAbbrevs(context, buffer, pos);
965966
pos = writeLocalDeclarationAbbrevs(context, buffer, pos);
@@ -1116,9 +1117,6 @@ private int writeClassLayoutAbbrevs(@SuppressWarnings("unused") DebugContext con
11161117
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_TU, buffer, pos);
11171118
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_CU, buffer, pos);
11181119
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_ARRAY, buffer, pos);
1119-
if (!dwarfSections.useHeapBase()) {
1120-
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_TU_2, buffer, pos);
1121-
}
11221120
return pos;
11231121
}
11241122

@@ -1147,10 +1145,6 @@ private int writeClassLayoutAbbrev(@SuppressWarnings("unused") DebugContext cont
11471145
} else {
11481146
pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos);
11491147
pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos);
1150-
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_TU_2) {
1151-
pos = writeAttrType(DwarfAttribute.DW_AT_data_location, buffer, pos);
1152-
pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos);
1153-
}
11541148
}
11551149
/*
11561150
* Now terminate.

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ enum AbbrevCode {
6868
CLASS_CONSTANT,
6969
NAMESPACE,
7070
CLASS_LAYOUT_TU,
71-
CLASS_LAYOUT_TU_2,
72-
CLASS_LAYOUT_ARRAY,
7371
CLASS_LAYOUT_CU,
72+
CLASS_LAYOUT_ARRAY,
7473
TYPE_POINTER_SIG,
7574
TYPE_POINTER,
7675
FOREIGN_TYPEDEF,
@@ -140,7 +139,7 @@ enum AbbrevCode {
140139
* The name of the type for header field hub which needs special case processing to remove tag
141140
* bits
142141
*/
143-
public static final String HUB_TYPE_NAME = "java.lang.Class";
142+
public static final String HUB_TYPE_NAME = "Encoded$Dynamic$Hub";
144143
/* Full byte/word values. */
145144
private final DwarfStrSectionImpl dwarfStrSection;
146145
private final DwarfAbbrevSectionImpl dwarfAbbrevSection;

0 commit comments

Comments
 (0)