Skip to content

Commit c64fc03

Browse files
Incorporate review feedback
Remove separate type unit for the layout of compressed types
1 parent bedc2cb commit c64fc03

File tree

8 files changed

+191
-128
lines changed

8 files changed

+191
-128
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public DebugInfoProvider.DebugTypeInfo.DebugTypeKind typeKind() {
5858
return DebugInfoProvider.DebugTypeInfo.DebugTypeKind.FOREIGN;
5959
}
6060

61+
/*
62+
* When we process a foreign pointer type for the .debug_info section we want to reuse its type
63+
* signature. After sizing the .debug_info the layout type signature contains the type signature
64+
* of the type this foreign pointer points to.
65+
*/
6166
public void setLayoutTypeSignature(long typeSignature) {
6267
this.layoutTypeSignature = typeSignature;
6368
}

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

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,26 +49,22 @@ public abstract class StructureTypeEntry extends TypeEntry {
4949
protected final List<FieldEntry> fields;
5050

5151
/**
52-
* The type signature of this types' layout.
52+
* The type signature of this types' layout. The layout of a type contains debug info of fields
53+
* and methods of a type, which is needed for representing the class hierarchy. The super type
54+
* entry in the debug info needs to directly contain the type info instead of a pointer.
5355
*/
5456
protected long layoutTypeSignature;
55-
protected long indirectLayoutTypeSignature;
5657

5758
public StructureTypeEntry(String typeName, int size) {
5859
super(typeName, size);
5960
this.fields = new ArrayList<>();
6061
this.layoutTypeSignature = 0;
61-
this.indirectLayoutTypeSignature = 0;
6262
}
6363

6464
public long getLayoutTypeSignature() {
6565
return layoutTypeSignature;
6666
}
6767

68-
public long getIndirectLayoutTypeSignature() {
69-
return indirectLayoutTypeSignature;
70-
}
71-
7268
public Stream<FieldEntry> fields() {
7369
return fields.stream();
7470
}
@@ -147,11 +143,5 @@ public void addDebugInfo(@SuppressWarnings("unused") DebugInfoBase debugInfoBase
147143
} else {
148144
this.layoutTypeSignature = debugTypeInfo.typeSignature(DwarfDebugInfo.LAYOUT_PREFIX);
149145
}
150-
// header and foreign types are never stored compressed
151-
if (!debugInfoBase.useHeapBase() || this instanceof HeaderTypeEntry || this instanceof ForeignTypeEntry) {
152-
this.indirectLayoutTypeSignature = layoutTypeSignature;
153-
} else {
154-
this.indirectLayoutTypeSignature = debugTypeInfo.typeSignature(DwarfDebugInfo.INDIRECT_PREFIX + DwarfDebugInfo.LAYOUT_PREFIX);
155-
}
156146
}
157147
}

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

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@ public abstract class TypeEntry {
4747
protected final String typeName;
4848

4949
/**
50-
* The type signature of this type.
50+
* The type signature of this type. This is a pointer to the underlying layout of the type.
5151
*/
5252
protected long typeSignature;
53-
protected long indirectTypeSignature;
53+
54+
/**
55+
* The type signature for the compressed type. This points to the compressed layout which
56+
* resolves oops to the actual address of an instances.
57+
*/
58+
protected long typeSignatureForCompressed;
5459

5560
/**
5661
* The offset of the java.lang.Class instance for this class in the image heap or -1 if no such
@@ -68,15 +73,15 @@ protected TypeEntry(String typeName, int size) {
6873
this.size = size;
6974
this.classOffset = -1;
7075
this.typeSignature = 0;
71-
this.indirectTypeSignature = 0;
76+
this.typeSignatureForCompressed = 0;
7277
}
7378

7479
public long getTypeSignature() {
7580
return typeSignature;
7681
}
7782

78-
public long getIndirectTypeSignature() {
79-
return indirectTypeSignature;
83+
public long getTypeSignatureForCompressed() {
84+
return typeSignatureForCompressed;
8085
}
8186

8287
public long getClassOffset() {
@@ -148,9 +153,9 @@ public void addDebugInfo(@SuppressWarnings("unused") DebugInfoBase debugInfoBase
148153
this.typeSignature = debugTypeInfo.typeSignature("");
149154
// primitives, header and foreign types are never stored compressed
150155
if (!debugInfoBase.useHeapBase() || this instanceof PrimitiveTypeEntry || this instanceof HeaderTypeEntry || this instanceof ForeignTypeEntry) {
151-
this.indirectTypeSignature = typeSignature;
156+
this.typeSignatureForCompressed = typeSignature;
152157
} else {
153-
this.indirectTypeSignature = debugTypeInfo.typeSignature(DwarfDebugInfo.INDIRECT_PREFIX);
158+
this.typeSignatureForCompressed = debugTypeInfo.typeSignature(DwarfDebugInfo.COMPRESSED_PREFIX);
154159
}
155160
}
156161
}

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

Lines changed: 64 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,18 @@
143143
* <li><code>abbrev_code == CLASS_LAYOUT_3, tag == DW_TAG_class_type, parent = CLASS_UNIT_1/2</code>
144144
* - Skeleton Java instance type structure definition for compilation units
145145
*
146-
* <li><code>abbrev_code == TYPE_POINTER, tag == DW_TAG_pointer_type, parent = TYPE_UNIT</code> - Is
147-
* either of
146+
* <li><code>abbrev_code == TYPE_POINTER_SIG, tag == DW_TAG_pointer_type, parent = TYPE_UNIT</code>
147+
* - Points to a type using its type signature and is either of
148148
* <ul>
149149
* <li>Java instance ref type</li>
150150
* <li>Java interface ref type</li>
151151
* <li>Java array ref type</li>
152-
* <li>Java indirect ref type</li> - used to type indirect oops that encode the address of an
152+
* </ul>
153+
*
154+
* <li><code>abbrev_code == TYPE_POINTER, tag == DW_TAG_pointer_type, parent = TYPE_UNIT</code> -
155+
* Points to a type using a 4 byte offset and is used for
156+
* <ul>
157+
* <li>Java compressed ref type</li> - used to type compressed oops that encode the address of an
153158
* object, whether by adding tag bits or representing the address as an offset from some base
154159
* address. these are used to type object references stored in static and instance fields. They are
155160
* not needed when typing local vars and parameters held in registers or on the stack as they appear
@@ -174,7 +179,7 @@
174179
* <li><code>abbrev_code == INTERFACE_LAYOUT, tag == DW_TAG_union_type, parent = TYPE_UNIT</code> -
175180
* Java array type structure definition
176181
*
177-
* <li><code>abbrev_code == INDIRECT_LAYOUT, tag == DW_TAG_class_type, parent = TYPE_UNIT</code> -
182+
* <li><code>abbrev_code == COMPRESSED_LAYOUT, tag == DW_TAG_class_type, parent = TYPE_UNIT</code> -
178183
* wrapper layout attaches address rewriting logic to the layout types that it wraps using a
179184
* <code>data_location</code> attribute
180185
*
@@ -386,7 +391,7 @@
386391
* which a debugger can use to decode the oop pointer to a raw address. n.b. this only applies in
387392
* the case where normal oop references are raw addresses (no compressed oops, no isolates). If a
388393
* heapbase register is being used then decoding logic is encoded for both normal classes and for
389-
* <code>java.lang.Class</code> using an indirect layout (see below).
394+
* <code>java.lang.Class</code> using a compressed layout (see below).
390395
*
391396
* <ul>
392397
*
@@ -403,7 +408,9 @@
403408
*
404409
* <li><code>DW_AT_decl_file : ... DW_FORM_data1/2</code> only for CLASS_LAYOUT_1/2
405410
*
406-
* <li><code>DW_AT_data_location : ... DW_FORM_expr_loc</code> n.b. only for CLASS_LAYOUT_2
411+
* <li><code>DW_AT_data_location : ... DW_FORM_expr_loc</code> only for CLASS_LAYOUT_2 - contains
412+
* the decoding logic for the layout of <code>java.lang.Class</code> if no compressed layout is
413+
* available
407414
*
408415
* </ul>
409416
*
@@ -537,21 +544,21 @@
537544
*
538545
* </ul>
539546
*
540-
* Indirect Instance Class Structure: The level 1 class layout DIE may be followed by a level 1
541-
* <code>INDIRECT_LAYOUT</code> DIE. The indirect layout is only needed when a heapbase register is
542-
* in use (isolates or compressed oops are enabled). This means that oop fields will hold encoded
543-
* oops. The indirect layout defines an empty wrapper class which declares the previous layout as
547+
* Compressed Instance Class Structure: The level 1 class layout DIE may be followed by a level 1
548+
* <code>COMPRESSED_LAYOUT</code> DIE. The compressed layout is only needed when a heapbase register
549+
* is in use (isolates or compressed oops are enabled). This means that oop fields will hold encoded
550+
* oops. The compressed layout defines an empty wrapper class which declares the previous layout as
544551
* its super class. This wrapper type also supplies a <code>data_location</code> attribute, ensuring
545-
* that indirect pointers to the class (see next item) are translated to raw addresses. The name of
546-
* the indirect type is constructed by prefixing the class name with
547-
* <code>DwarfDebugInfo.INDIRECT_PREFIX</code>. This DIE has only one child DIE with type
548-
* SUPER_REFERENCE (see above). This effectively embeds the standard layout type in the indirect
549-
* layout as a type compatible referent for the Java oop. The size of the indirect layout is the
552+
* that compressed pointers to the class (see next item) are translated to raw addresses. The name
553+
* of the compressed type is constructed by prefixing the class name with
554+
* <code>DwarfDebugInfo.COMPRESSED_PREFIX</code>. This DIE has only one child DIE with type
555+
* SUPER_REFERENCE (see above). This effectively embeds the standard layout type in the compressed
556+
* layout as a type compatible referent for the Java oop. The size of the compressed layout is the
550557
* same as the size of the class layout.
551558
*
552559
* <ul>
553560
*
554-
* <li><code>abbrev_code == INDIRECT_LAYOUT, tag == DW_TAG_class_type, has_children</code>
561+
* <li><code>abbrev_code == COMPRESSED_LAYOUT, tag == DW_TAG_class_type, has_children</code>
555562
*
556563
* <li><code>DW_AT_name : ........ DW_FORM_strp</code>
557564
*
@@ -562,16 +569,16 @@
562569
* </ul>
563570
*
564571
* Instance Class Reference Types: The level 1 <code>CLASS_LAYOUT</code> and
565-
* <code>INDIRECT_LAYOUT</code> DIEs are followed by level 1 DIEs defining pointers to the
572+
* <code>COMPRESSED_LAYOUT</code> DIEs are followed by level 1 DIEs defining pointers to the
566573
* respective class layouts. A <code>TYPE_POINTER</code> DIE defines a pointer type for the
567574
* <code>CLASS_LAYOUT</code> type and is used to type pointers which directly address an instance.
568575
* It is used to type local and parameter var references whether located in a register or on the
569576
* stack. It may be followed by another <code>TYPE_POINTER</code> DIE which defines a pointer type
570-
* for the class's <code>INDIRECT_LAYOUT</code> type. This is used to type references to instances
577+
* for the class's <code>COMPRESSED_LAYOUT</code> type. This is used to type references to instances
571578
* of the class located in a static or instance field. These latter references require address
572579
* translation by masking off tag bits and/or rebasing from an offset to a raw address. The logic
573580
* for this translation is encoded in the <code>data_location</code> attribute of the corresponding
574-
* <code>INDIRECT_LAYOUT</code> DIE.
581+
* <code>COMPRESSED_LAYOUT</code> DIE.
575582
*
576583
* <ul>
577584
*
@@ -767,19 +774,19 @@
767774
*
768775
* </ul>
769776
*
770-
* The immediately following DIE is an INDIRECT_LAYOUT (see above) that wraps the array layout as
777+
* The immediately following DIE is an COMPRESSED_LAYOUT (see above) that wraps the array layout as
771778
* its super type (just as with class layouts). The wrapper type supplies a data_location attribute,
772-
* allowing indirect pointers to the array to be translated to raw addresses. The name of the
773-
* indirect array type is constructed by prefixing the array name with
774-
* <code>DwarfDebugInfo.INDIRECT_PREFIX</code>. This DIE has only one child DIE with type
779+
* allowing compressed pointers to the array to be translated to raw addresses. The name of the
780+
* compressed array type is constructed by prefixing the array name with
781+
* <code>DwarfDebugInfo.COMPRESSED_PREFIX</code>. This DIE has only one child DIE with type
775782
* <code>SUPER_REFERENCE</code> (see above). The latter references the array layout DIE, effectively
776-
* embedding the standard array layout type in the indirect layout. The size of the indirect layout
777-
* is the same as the size of the array layout.
783+
* embedding the standard array layout type in the compressed layout. The size of the compressed
784+
* layout is the same as the size of the array layout.
778785
* <p>
779786
*
780787
* The third and fourth DIEs define array reference types as a pointers to the underlying structure
781788
* layout types. As with classes, there is a TYPE_POINTER type for raw address references used to
782-
* type local and param vars and a (indirect) TYPE_POINTER type (see above) for array references
789+
* type local and param vars and a (compressed) TYPE_POINTER type (see above) for array references
783790
* stored in static and instance fields.
784791
*
785792
* n.b. the name used in the ARRAY_LAYOUT DIE is the Java array name. This is deliberately
@@ -821,18 +828,18 @@
821828
*
822829
* </ul>
823830
*
824-
* A second level 1 DIE provides an indirect layout that wraps the interface layout as its super
831+
* A second level 1 DIE provides a compressed layout that wraps the interface layout as its super
825832
* type (just as with class layouts). The wrapper type supplies a <code>data_location</code>
826-
* attribute, allowing indirect pointers to the interface to be translated to raw addresses. The
827-
* name of the indirect interface type is constructed by prefixing the interface name with
828-
* <code>DwarfDebugInfo.INDIRECT_PREFIX</code>. This DIE has only one child DIE with type
833+
* attribute, allowing compressed pointers to the interface to be translated to raw addresses. The
834+
* name of the compressed interface type is constructed by prefixing the interface name with
835+
* <code>DwarfDebugInfo.COMPRESSED_PREFIX</code>. This DIE has only one child DIE with type
829836
* <code>sup[er_reference</code> (see above). The latter references the interface layout DIE,
830-
* effectively embedding the standard interface layout type in the indirect layout. The size of the
831-
* indirect layout is the same as the size of the interface layout.
837+
* effectively embedding the standard interface layout type in the compressed layout. The size of
838+
* the compressed layout is the same as the size of the interface layout.
832839
*
833840
* The third and fourth DIEs define interface reference types as a pointers to the underlying
834841
* structure layout types. As with classes, there is an TYPE_POINTER type for raw address references
835-
* used to type local and param vars and an (indirect) TYPE_POINTER type (see above) for interface
842+
* used to type local and param vars and a (compressed) TYPE_POINTER type (see above) for interface
836843
* references stored in static and instance fields.
837844
*
838845
* A second level 1 defines a pointer to this layout type.
@@ -918,7 +925,7 @@ public int writeAbbrevs(DebugContext context, byte[] buffer, int p) {
918925
pos = writeNamespaceAbbrev(context, buffer, pos);
919926

920927
pos = writeClassLayoutAbbrevs(context, buffer, pos);
921-
pos = writeClassReferenceAbbrev(context, buffer, pos);
928+
pos = writeClassReferenceAbbrevs(context, buffer, pos);
922929
pos = writeMethodDeclarationAbbrevs(context, buffer, pos);
923930
pos = writeFieldDeclarationAbbrevs(context, buffer, pos);
924931

@@ -943,16 +950,16 @@ public int writeAbbrevs(DebugContext context, byte[] buffer, int p) {
943950
pos = writeInlinedSubroutineAbbrev(buffer, pos, true);
944951

945952
/*
946-
* if we address rebasing is required then then we need to use indirect layout types
947-
* supplied with a suitable data_location attribute and indirect pointer types to ensure
948-
* that gdb converts offsets embedded in static or instance fields to raw pointers.
949-
* Transformed addresses are typed using pointers to the underlying layout.
953+
* if we address rebasing is required then we need to use compressed layout types supplied
954+
* with a suitable data_location attribute and compressed pointer types to ensure that gdb
955+
* converts offsets embedded in static or instance fields to raw pointers. Transformed
956+
* addresses are typed using pointers to the underlying layout.
950957
*
951-
* if address rebasing is not required then we a data_location attribute on the layout type
958+
* if address rebasing is not required then a data_location attribute on the layout type
952959
* will ensure that address tag bits are removed.
953960
*/
954961
if (dwarfSections.useHeapBase()) {
955-
pos = writeIndirectLayoutAbbrev(context, buffer, pos);
962+
pos = writeCompressedLayoutAbbrev(context, buffer, pos);
956963
}
957964

958965
pos = writeParameterDeclarationAbbrevs(context, buffer, pos);
@@ -1152,17 +1159,25 @@ private int writeClassLayoutAbbrev(@SuppressWarnings("unused") DebugContext cont
11521159
return pos;
11531160
}
11541161

1155-
private int writeClassReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
1162+
private int writeClassReferenceAbbrevs(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
1163+
int pos = p;
1164+
pos = writeClassReferenceAbbrev(context, AbbrevCode.TYPE_POINTER_SIG, buffer, pos);
1165+
pos = writeClassReferenceAbbrev(context, AbbrevCode.TYPE_POINTER, buffer, pos);
1166+
return pos;
1167+
}
1168+
1169+
private int writeClassReferenceAbbrev(@SuppressWarnings("unused") DebugContext context, AbbrevCode abbrevCode, byte[] buffer, int p) {
11561170
int pos = p;
11571171

11581172
/* A pointer to the class struct type. */
1159-
pos = writeAbbrevCode(AbbrevCode.TYPE_POINTER, buffer, pos);
1173+
pos = writeAbbrevCode(abbrevCode, buffer, pos);
11601174
pos = writeTag(DwarfTag.DW_TAG_pointer_type, buffer, pos);
11611175
pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_no, buffer, pos);
11621176
pos = writeAttrType(DwarfAttribute.DW_AT_byte_size, buffer, pos);
11631177
pos = writeAttrForm(DwarfForm.DW_FORM_data1, buffer, pos);
11641178
pos = writeAttrType(DwarfAttribute.DW_AT_type, buffer, pos);
1165-
pos = writeAttrForm(DwarfForm.DW_FORM_ref_sig8, buffer, pos);
1179+
pos = writeAttrForm(abbrevCode == AbbrevCode.TYPE_POINTER_SIG ? DwarfForm.DW_FORM_ref_sig8 : DwarfForm.DW_FORM_ref4, buffer, pos);
1180+
11661181
/*
11671182
* Now terminate.
11681183
*/
@@ -1563,18 +1578,18 @@ private int writeSuperReferenceAbbrev(@SuppressWarnings("unused") DebugContext c
15631578
return pos;
15641579
}
15651580

1566-
private int writeIndirectLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
1581+
private int writeCompressedLayoutAbbrev(@SuppressWarnings("unused") DebugContext context, byte[] buffer, int p) {
15671582
int pos = p;
15681583

15691584
/*
1570-
* oops are not necessarily raw addresses. they may contains pointer bits or be offsets from
1571-
* a base register. An indirect layout wraps a standard layout adding a data_location that
1572-
* translates indirect an oop to a raw address. It is used as the base for an indirect
1585+
* oops are not necessarily raw addresses. They may contain pointer bits or be offsets from
1586+
* a base register. A compressed layout wraps a standard layout adding a data_location that
1587+
* translates compressed oops to a raw addresses. It is used as the base for a compressed
15731588
* pointer type that is used to type values that need translation to a raw address i.e.
15741589
* values stored in static and instance fields.
15751590
*/
1576-
/* the type for an indirect layout that includes address translation info */
1577-
pos = writeAbbrevCode(AbbrevCode.INDIRECT_LAYOUT, buffer, pos);
1591+
/* The type for a compressed layout that includes address translation info */
1592+
pos = writeAbbrevCode(AbbrevCode.COMPRESSED_LAYOUT, buffer, pos);
15781593
pos = writeTag(DwarfTag.DW_TAG_class_type, buffer, pos);
15791594
pos = writeHasChildren(DwarfHasChildren.DW_CHILDREN_yes, buffer, pos);
15801595
pos = writeAttrType(DwarfAttribute.DW_AT_name, buffer, pos);

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ enum AbbrevCode {
7070
CLASS_LAYOUT_1,
7171
CLASS_LAYOUT_2,
7272
CLASS_LAYOUT_3,
73+
TYPE_POINTER_SIG,
7374
TYPE_POINTER,
7475
FOREIGN_TYPEDEF,
7576
FOREIGN_STRUCT,
7677
METHOD_LOCATION,
7778
STATIC_FIELD_LOCATION,
7879
ARRAY_LAYOUT,
7980
INTERFACE_LAYOUT,
80-
INDIRECT_LAYOUT,
81+
COMPRESSED_LAYOUT,
8182
/* Level 2 DIEs. */
8283
METHOD_DECLARATION,
8384
METHOD_DECLARATION_STATIC,
@@ -128,7 +129,7 @@ enum AbbrevCode {
128129
* A prefix used to label indirect types used to ensure gdb performs oop reference --> raw
129130
* address translation
130131
*/
131-
public static final String INDIRECT_PREFIX = "_z_.";
132+
public static final String COMPRESSED_PREFIX = "_z_.";
132133
/*
133134
* A prefix used for type signature generation to generate unique type signatures for type
134135
* layout type units

0 commit comments

Comments
 (0)