Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions substratevm/debug/gdbpy/gdb-debughelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class SVMUtil:
string_type = gdb.lookup_type("java.lang.String")
enum_type = gdb.lookup_type("java.lang.Enum")
object_type = gdb.lookup_type("java.lang.Object")
hub_type = gdb.lookup_type("java.lang.Class")
hub_type = gdb.lookup_type("Encoded$Dynamic$Hub")
null = gdb.Value(0).cast(object_type.pointer())
classloader_type = gdb.lookup_type("java.lang.ClassLoader")
wrapper_types = [gdb.lookup_type(f'java.lang.{x}') for x in
Expand Down Expand Up @@ -141,7 +141,7 @@ def get_uncompressed_type(cls, t: gdb.Type) -> gdb.Type:
# compressed types only exist for java type which are either struct or union
if t.code != gdb.TYPE_CODE_STRUCT and t.code != gdb.TYPE_CODE_UNION:
return t
result = cls.get_base_class(t) if cls.is_compressed(t) else t
result = cls.get_base_class(t) if (cls.is_compressed(t) and t != cls.hub_type) else t
trace(f'<SVMUtil> - get_uncompressed_type({t}) = {result}')
return result

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

@classmethod
def is_compressed(cls, t: gdb.Type) -> bool:
# for the hub type we always want handle it as compressed as there is no clear distinction in debug info for
# the hub field, and it may always have an expression in the type's data_location attribute
if cls.get_basic_type(t) == cls.hub_type:
return True

type_name = cls.get_basic_type(t).name
if type_name is None:
# fallback to the GDB type printer for t
Expand Down Expand Up @@ -363,6 +368,9 @@ def get_classloader_namespace(cls, obj: gdb.Value) -> str:
def get_rtt(cls, obj: gdb.Value) -> gdb.Type:
static_type = cls.get_basic_type(obj.type)

if static_type == cls.hub_type:
return cls.hub_type

# check for interfaces and cast them to Object to make the hub accessible
if cls.get_uncompressed_type(cls.get_basic_type(obj.type)).code == gdb.TYPE_CODE_UNION:
obj = cls.cast_to(obj, cls.object_type)
Expand Down
237 changes: 161 additions & 76 deletions substratevm/mx.substratevm/testhello.py

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ protected MethodEntry processMethod(DebugMethodInfo debugMethodInfo, DebugInfoBa
}

@Override
protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
FieldEntry fieldEntry = super.addField(debugFieldInfo, debugInfoBase, debugContext);
protected FieldEntry createField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
FieldEntry fieldEntry = super.createField(debugFieldInfo, debugInfoBase, debugContext);
return fieldEntry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocalValueInfo;
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugLocationInfo;
import com.oracle.objectfile.debuginfo.DebugInfoProvider.DebugTypeInfo.DebugTypeKind;
import com.oracle.objectfile.elf.dwarf.DwarfDebugInfo;

import jdk.graal.compiler.debug.DebugContext;
import jdk.vm.ci.meta.ResolvedJavaType;
Expand Down Expand Up @@ -135,6 +134,10 @@ public abstract class DebugInfoBase {
* Handle on class entry for java.lang.Object.
*/
private ClassEntry objectClass;
/**
* The type entry for java.lang.Class.
*/
private ClassEntry classClass;
/**
* List of all top level compiled methods found in debug info. These ought to arrive via the
* debug info API in ascending address range order.
Expand Down Expand Up @@ -202,11 +205,6 @@ public abstract class DebugInfoBase {
*/
private int compiledCodeMax;

/**
* The type entry for java.lang.Class.
*/
private ClassEntry hubClassEntry;

@SuppressWarnings("this-escape")
public DebugInfoBase(ByteOrder byteOrder) {
this.byteOrder = byteOrder;
Expand All @@ -218,7 +216,6 @@ public DebugInfoBase(ByteOrder byteOrder) {
this.pointerSize = 0;
this.objectAlignment = 0;
this.numAlignmentBits = 0;
this.hubClassEntry = null;
this.compiledCodeMax = 0;
// create and index an empty dir with index 0.
ensureDirEntry(EMPTY_PATH);
Expand Down Expand Up @@ -372,9 +369,6 @@ private TypeEntry createTypeEntry(String typeName, String fileName, Path filePat
case INSTANCE: {
FileEntry fileEntry = addFileEntry(fileName, filePath);
typeEntry = new ClassEntry(typeName, fileEntry, size);
if (typeEntry.getTypeName().equals(DwarfDebugInfo.HUB_TYPE_NAME)) {
hubClassEntry = (ClassEntry) typeEntry;
}
break;
}
case INTERFACE: {
Expand Down Expand Up @@ -423,6 +417,9 @@ private TypeEntry addTypeEntry(ResolvedJavaType idType, String typeName, String
if (idType == null) {
headerType = (HeaderTypeEntry) typeEntry;
}
if (typeName.equals("java.lang.Class")) {
classClass = (ClassEntry) typeEntry;
}
if (typeName.equals("java.lang.Object")) {
objectClass = (ClassEntry) typeEntry;
}
Expand Down Expand Up @@ -479,6 +476,12 @@ public ClassEntry lookupObjectClass() {
return objectClass;
}

public ClassEntry lookupClassClass() {
// this should only be looked up after all types have been notified
assert classClass != null;
return classClass;
}

private void addPrimaryRange(PrimaryRange primaryRange, DebugCodeInfo debugCodeInfo, ClassEntry classEntry) {
CompiledMethodEntry compiledMethod = classEntry.indexPrimary(primaryRange, debugCodeInfo.getFrameSizeChanges(), debugCodeInfo.getFrameSize());
indexCompiledMethod(compiledMethod);
Expand Down Expand Up @@ -737,14 +740,6 @@ public String getCachePath() {
return cachePath;
}

public boolean isHubClassEntry(StructureTypeEntry typeEntry) {
return typeEntry.getTypeName().equals(DwarfDebugInfo.HUB_TYPE_NAME);
}

public ClassEntry getHubClassEntry() {
return hubClassEntry;
}

private static void collectFilesAndDirs(ClassEntry classEntry) {
// track files and dirs we have already seen so that we only add them once
EconomicSet<FileEntry> visitedFiles = EconomicSet.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,16 @@

public class HeaderTypeEntry extends StructureTypeEntry {

FieldEntry hubField;

public HeaderTypeEntry(String typeName, int size) {
super(typeName, size);
}

public FieldEntry getHubField() {
return hubField;
}

@Override
public DebugTypeKind typeKind() {
return DebugTypeKind.HEADER;
Expand All @@ -49,5 +55,6 @@ public void addDebugInfo(DebugInfoBase debugInfoBase, DebugTypeInfo debugTypeInf
assert debugTypeInfo.typeName().equals(typeName);
DebugHeaderTypeInfo debugHeaderTypeInfo = (DebugHeaderTypeInfo) debugTypeInfo;
debugHeaderTypeInfo.fieldInfoProvider().forEach(debugFieldInfo -> this.processField(debugFieldInfo, debugInfoBase, debugContext));
hubField = createField(debugHeaderTypeInfo.hubField(), debugInfoBase, debugContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ public int fieldCount() {

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

protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
protected FieldEntry createField(DebugFieldInfo debugFieldInfo, DebugInfoBase debugInfoBase, DebugContext debugContext) {
String fieldName = debugInfoBase.uniqueDebugString(debugFieldInfo.name());
ResolvedJavaType valueType = debugFieldInfo.valueType();
String valueTypeName = valueType.toJavaName();
Expand All @@ -96,9 +97,7 @@ protected FieldEntry addField(DebugFieldInfo debugFieldInfo, DebugInfoBase debug
* substitution
*/
FileEntry fileEntry = debugInfoBase.ensureFileEntry(debugFieldInfo);
FieldEntry fieldEntry = new FieldEntry(fileEntry, fieldName, this, valueTypeEntry, fieldSize, fieldoffset, fieldIsEmbedded, fieldModifiers);
fields.add(fieldEntry);
return fieldEntry;
return new FieldEntry(fileEntry, fieldName, this, valueTypeEntry, fieldSize, fieldoffset, fieldIsEmbedded, fieldModifiers);
}

String memberModifiers(int modifiers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ interface DebugPrimitiveTypeInfo extends DebugTypeInfo {
interface DebugHeaderTypeInfo extends DebugTypeInfo {

Stream<DebugFieldInfo> fieldInfoProvider();

DebugFieldInfo hubField();
}

interface DebugMemberInfo extends DebugFileInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -936,8 +936,7 @@ public int writeAbbrevs(DebugContext context, byte[] buffer, int p) {
pos = writeForeignTypedefAbbrev(context, buffer, pos);
pos = writeForeignStructAbbrev(context, buffer, pos);

pos = writeHeaderFieldAbbrev(context, buffer, pos);
pos = writeArrayElementFieldAbbrev(context, buffer, pos);
pos = writeFieldAbbrevs(context, buffer, pos);
pos = writeArrayDataTypeAbbrevs(context, buffer, pos);
pos = writeArraySubrangeTypeAbbrev(context, buffer, pos);
pos = writeMethodLocationAbbrev(context, buffer, pos);
Expand All @@ -957,10 +956,11 @@ public int writeAbbrevs(DebugContext context, byte[] buffer, int p) {
*
* if address rebasing is not required then a data_location attribute on the layout type
* will ensure that address tag bits are removed.
*
* The compressed layout is also used for representing the decode step for dynamic hubs.
* I.e. this is also required for builds without isolates
*/
if (dwarfSections.useHeapBase()) {
pos = writeCompressedLayoutAbbrev(context, buffer, pos);
}
pos = writeCompressedLayoutAbbrev(context, buffer, pos);

pos = writeParameterDeclarationAbbrevs(context, buffer, pos);
pos = writeLocalDeclarationAbbrevs(context, buffer, pos);
Expand Down Expand Up @@ -1114,12 +1114,9 @@ private int writeNamespaceAbbrev(@SuppressWarnings("unused") DebugContext contex

private int writeClassLayoutAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
int pos = p;
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_1, buffer, pos);
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_3, buffer, pos);
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_4, buffer, pos);
if (!dwarfSections.useHeapBase()) {
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_2, buffer, pos);
}
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_TU, buffer, pos);
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_CU, buffer, pos);
pos = writeClassLayoutAbbrev(context, AbbrevCode.CLASS_LAYOUT_ARRAY, buffer, pos);
return pos;
}

Expand All @@ -1131,12 +1128,12 @@ private int writeClassLayoutAbbrev(@SuppressWarnings("unused") DebugContext cont
pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos);
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_3 || abbrevCode == AbbrevCode.CLASS_LAYOUT_4) {
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_ARRAY || abbrevCode == AbbrevCode.CLASS_LAYOUT_CU) {
pos = writeAttrType(DwarfAttribute.DW_AT_declaration, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_flag, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_signature, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_ref_sig8, buffer, pos);
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_4) {
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_CU) {
pos = writeAttrType(DwarfAttribute.DW_AT_decl_file, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos);
/*-
Expand All @@ -1148,10 +1145,6 @@ private int writeClassLayoutAbbrev(@SuppressWarnings("unused") DebugContext cont
} else {
pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos);
if (abbrevCode == AbbrevCode.CLASS_LAYOUT_2) {
pos = writeAttrType(DwarfAttribute.DW_AT_data_location, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_expr_loc, buffer, pos);
}
}
/*
* Now terminate.
Expand Down Expand Up @@ -1409,38 +1402,27 @@ private int writeForeignStructAbbrev(@SuppressWarnings("unused") DebugContext co
return pos;
}

private int writeHeaderFieldAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
private int writeFieldAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
int pos = p;

pos = writeAbbrevCode(AbbrevCode.HEADER_FIELD, buffer, pos);
pos = writeTag(DwarfTag.DW_TAG_member, buffer, pos);
pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_ref_sig8, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_data_member_location, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos);
/*
* Now terminate.
*/
pos = writeAttrType(DwarfAttribute.DW_AT_null, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_null, buffer, pos);
pos = writeFieldAbbrev(context, AbbrevCode.STRUCT_FIELD_SIG, buffer, pos);
pos = writeFieldAbbrev(context, AbbrevCode.STRUCT_FIELD, buffer, pos);
return pos;
}

private int writeArrayElementFieldAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
private int writeFieldAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) {
int pos = p;

pos = writeAbbrevCode(AbbrevCode.ARRAY_ELEMENT_FIELD, buffer, pos);
pos = writeAbbrevCode(abbrevCode, buffer, pos);
pos = writeTag(DwarfTag.DW_TAG_member, buffer, pos);
pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_strp, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos);
if (abbrevCode == AbbrevCode.STRUCT_FIELD_SIG) {
pos = writeAttrForm(DwarfForm.DW_FORM_ref_sig8, buffer, pos);
} else {
pos = writeAttrForm(DwarfForm.DW_FORM_ref_addr, buffer, pos);
}
pos = writeAttrType(DwarfAttribute.DW_AT_data_member_location, buffer, pos);
pos = writeAttrForm(DwarfForm.DW_FORM_data2, buffer, pos);
pos = writeAttrType(DwarfAttribute.DW_AT_accessibility, buffer, pos);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ enum AbbrevCode {
OBJECT_HEADER,
CLASS_CONSTANT,
NAMESPACE,
CLASS_LAYOUT_1,
CLASS_LAYOUT_2,
CLASS_LAYOUT_3,
CLASS_LAYOUT_4,
CLASS_LAYOUT_TU,
CLASS_LAYOUT_CU,
CLASS_LAYOUT_ARRAY,
TYPE_POINTER_SIG,
TYPE_POINTER,
FOREIGN_TYPEDEF,
Expand All @@ -88,8 +87,8 @@ enum AbbrevCode {
FIELD_DECLARATION_2,
FIELD_DECLARATION_3,
FIELD_DECLARATION_4,
HEADER_FIELD,
ARRAY_ELEMENT_FIELD,
STRUCT_FIELD_SIG,
STRUCT_FIELD,
ARRAY_DATA_TYPE_1,
ARRAY_DATA_TYPE_2,
ARRAY_SUBRANGE,
Expand Down Expand Up @@ -140,7 +139,7 @@ enum AbbrevCode {
* The name of the type for header field hub which needs special case processing to remove tag
* bits
*/
public static final String HUB_TYPE_NAME = "java.lang.Class";
public static final String HUB_TYPE_NAME = "Encoded$Dynamic$Hub";
/* Full byte/word values. */
private final DwarfStrSectionImpl dwarfStrSection;
private final DwarfAbbrevSectionImpl dwarfAbbrevSection;
Expand Down
Loading
Loading