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
53 changes: 28 additions & 25 deletions substratevm/debug/gdbpy/gdb-debughelpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ class SVMUtil:
compressed_ref_prefix = '_z_.'

use_heap_base = try_or_else(lambda: bool(gdb.parse_and_eval('(int)__svm_use_heap_base')), True, gdb.error)
compressed_shift = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_compressed_shift')), 0, gdb.error)
oop_tags_mask = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_oop_tags_mask')), 0, gdb.error)
compression_shift = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_compression_shift')), 0, gdb.error)
reserved_bits_mask = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_reserved_bits_mask')), 0, gdb.error)
object_alignment = try_or_else(lambda: int(gdb.parse_and_eval('(int)__svm_object_alignment')), 0, gdb.error)

string_type = gdb.lookup_type("java.lang.String")
Expand Down Expand Up @@ -190,31 +190,34 @@ def get_compressed_type(cls, t: gdb.Type) -> gdb.Type:
return gdb.lookup_type(type_name)

@classmethod
def get_compressed_adr(cls, obj: gdb.Value) -> int:
def get_compressed_oop(cls, obj: gdb.Value) -> int:
# use compressed ref if available - only compute it if necessary
if obj.type.code == gdb.TYPE_CODE_PTR and cls.is_compressed(obj.type):
return int(obj)

absolute_adr = adr(obj)
if absolute_adr == 0:
return absolute_adr
obj_adr = adr(obj)
if obj_adr == 0:
return obj_adr

# recreate correct address for compressed oops
# For an explanation of the conversion rules see com.oracle.svm.core.heap.ReferenceAccess
# 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
oop_compressed_shift = cls.compressed_shift
oop_tag_shift = int.bit_count(cls.oop_tags_mask)
oop_align_shift = int.bit_count(cls.object_alignment - 1)
compressed_adr = absolute_adr
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)
compressed_oop = obj_adr
if cls.use_heap_base:
compressed_adr -= int(SVMUtil.get_heap_base())
if is_hub:
if oop_compressed_shift == 0:
oop_compressed_shift = oop_align_shift
compressed_adr = compressed_adr << oop_tag_shift
compressed_adr = compressed_adr >> oop_compressed_shift
compressed_oop -= int(SVMUtil.get_heap_base())
assert compression_shift >= 0
compressed_oop = compressed_oop >> compression_shift
if is_hub:
assert num_alignment_bits >= 0
compressed_oop = compressed_oop << num_alignment_bits
assert num_reserved_bits >= 0
compressed_oop = compressed_oop >> num_reserved_bits

return compressed_adr
return compressed_oop

@classmethod
def get_unqualified_type_name(cls, qualified_type_name: str) -> str:
Expand All @@ -237,7 +240,7 @@ def is_compressed(cls, t: gdb.Type) -> bool:
@classmethod
def adr_str(cls, obj: gdb.Value) -> str:
if not svm_print_address.absolute_adr and cls.is_compressed(obj.type):
result = f' @z({hex(cls.get_compressed_adr(obj))})'
result = f' @z({hex(cls.get_compressed_oop(obj))})'
else:
result = f' @({hex(adr(obj))})'
trace(f'<SVMUtil> - adr_str({hex(adr(obj))}) = {result}')
Expand Down Expand Up @@ -440,9 +443,9 @@ def cast_to(cls, obj: gdb.Value, t: gdb.Type) -> gdb.Value:

# get objects address, take care of compressed oops
if cls.is_compressed(t):
obj_adr = cls.get_compressed_adr(obj)
obj_oop = cls.get_compressed_oop(obj)
else:
obj_adr = adr(obj)
obj_oop = adr(obj)

trace(f'<SVMUtil> - cast_to({hex(adr(obj))}, {t})')
if t.code != gdb.TYPE_CODE_PTR:
Expand All @@ -451,7 +454,7 @@ def cast_to(cls, obj: gdb.Value, t: gdb.Type) -> gdb.Value:
trace(f'<SVMUtil> - cast_to({hex(adr(obj))}, {t}) returned')
# just use the raw pointer value and cast it instead the obj
# casting the obj directly results in issues with compressed oops
return obj if t == obj.type else gdb.Value(obj_adr).cast(t)
return obj if t == obj.type else gdb.Value(obj_oop).cast(t)

@classmethod
def get_symbol_adr(cls, symbol: str) -> int:
Expand Down Expand Up @@ -1236,8 +1239,8 @@ def cast_to_rtt(obj: gdb.Value, obj_str: str) -> tuple: # tuple[gdb.Value, str]
if static_type.name == rtt.name:
return obj, obj_str
else:
obj_adr = SVMUtil.get_compressed_adr(obj) if SVMUtil.is_compressed(rtt) else adr(obj)
return obj, f"(('{rtt.name}' *)({obj_adr}))"
obj_oop = SVMUtil.get_compressed_oop(obj) if SVMUtil.is_compressed(rtt) else adr(obj)
return obj, f"(('{rtt.name}' *)({obj_oop}))"

# Define the token specifications
token_specification = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -167,27 +167,31 @@ public abstract class DebugInfoBase {
/**
* Number of bits oops are left shifted by when using compressed oops.
*/
private int oopCompressShift;
private int compressionShift;
/**
* Bit mask used for tagging oops.
*/
private int reservedBitsMask;
/**
* Number of low order bits used for tagging oops.
*/
private int oopTagsCount;
private int numReservedBits;
/**
* Number of bytes used to store an oop reference.
*/
private int oopReferenceSize;
private int referenceSize;
/**
* Number of bytes used to store a raw pointer.
*/
private int pointerSize;
/**
* Alignment of object memory area (and, therefore, of any oop) in bytes.
*/
private int oopAlignment;
private int objectAlignment;
/**
* Number of bits in oop which are guaranteed 0 by virtue of alignment.
*/
private int oopAlignShift;
private int numAlignmentBits;
/**
* The compilation directory in which to look for source files as a {@link String}.
*/
Expand All @@ -207,12 +211,13 @@ public abstract class DebugInfoBase {
public DebugInfoBase(ByteOrder byteOrder) {
this.byteOrder = byteOrder;
this.useHeapBase = true;
this.oopTagsCount = 0;
this.oopCompressShift = 0;
this.oopReferenceSize = 0;
this.reservedBitsMask = 0;
this.numReservedBits = 0;
this.compressionShift = 0;
this.referenceSize = 0;
this.pointerSize = 0;
this.oopAlignment = 0;
this.oopAlignShift = 0;
this.objectAlignment = 0;
this.numAlignmentBits = 0;
this.hubClassEntry = null;
this.compiledCodeMax = 0;
// create and index an empty dir with index 0.
Expand Down Expand Up @@ -245,35 +250,33 @@ public void installDebugInfo(DebugInfoProvider debugInfoProvider) {
/*
* Save count of low order tag bits that may appear in references.
*/
int oopTagsMask = debugInfoProvider.oopTagsMask();
reservedBitsMask = debugInfoProvider.reservedBitsMask();

/* Tag bits must be between 0 and 32 for us to emit as DW_OP_lit<n>. */
assert oopTagsMask >= 0 && oopTagsMask < 32;
/* Mask must be contiguous from bit 0. */
assert ((oopTagsMask + 1) & oopTagsMask) == 0;
assert ((reservedBitsMask + 1) & reservedBitsMask) == 0;

oopTagsCount = Integer.bitCount(oopTagsMask);
numReservedBits = Integer.bitCount(reservedBitsMask);

/* Save amount we need to shift references by when loading from an object field. */
oopCompressShift = debugInfoProvider.oopCompressShift();
compressionShift = debugInfoProvider.compressionShift();

/* shift bit count must be either 0 or 3 */
assert (oopCompressShift == 0 || oopCompressShift == 3);
assert (compressionShift == 0 || compressionShift == 3);

/* Save number of bytes in a reference field. */
oopReferenceSize = debugInfoProvider.oopReferenceSize();
referenceSize = debugInfoProvider.referenceSize();

/* Save pointer size of current target. */
pointerSize = debugInfoProvider.pointerSize();

/* Save alignment of a reference. */
oopAlignment = debugInfoProvider.oopAlignment();
objectAlignment = debugInfoProvider.objectAlignment();

/* Save alignment of a reference. */
oopAlignShift = Integer.bitCount(oopAlignment - 1);
numAlignmentBits = Integer.bitCount(objectAlignment - 1);

/* Reference alignment must be 8 bytes. */
assert oopAlignment == 8;
assert objectAlignment == 8;

/* retrieve limit for Java code address range */
compiledCodeMax = debugInfoProvider.compiledCodeMax();
Expand Down Expand Up @@ -702,32 +705,32 @@ public boolean useHeapBase() {
return useHeapBase;
}

public byte oopTagsMask() {
return (byte) ((1 << oopTagsCount) - 1);
public int reservedBitsMask() {
return reservedBitsMask;
}

public byte oopTagsShift() {
return (byte) oopTagsCount;
public int numReservedBits() {
return numReservedBits;
}

public int oopCompressShift() {
return oopCompressShift;
public int compressionShift() {
return compressionShift;
}

public int oopReferenceSize() {
return oopReferenceSize;
public int referenceSize() {
return referenceSize;
}

public int pointerSize() {
return pointerSize;
}

public int oopAlignment() {
return oopAlignment;
public int objectAlignment() {
return objectAlignment;
}

public int oopAlignShift() {
return oopAlignShift;
public int numAlignmentBits() {
return numAlignmentBits;
}

public String getCachePath() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2020, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
Expand Down Expand Up @@ -47,17 +47,17 @@ public interface DebugInfoProvider {
/**
* Number of bits oops are left shifted by when using compressed oops.
*/
int oopCompressShift();
int compressionShift();

/**
* Mask selecting low order bits used for tagging oops.
*/
int oopTagsMask();
int reservedBitsMask();

/**
* Number of bytes used to store an oop reference.
*/
int oopReferenceSize();
int referenceSize();

/**
* Number of bytes used to store a raw pointer.
Expand All @@ -67,7 +67,7 @@ public interface DebugInfoProvider {
/**
* Alignment of object memory area (and, therefore, of any oop) in bytes.
*/
int oopAlignment();
int objectAlignment();

int compiledCodeMax();

Expand Down
Loading
Loading