diff --git a/substratevm/debug/gdbpy/gdb-debughelpers.py b/substratevm/debug/gdbpy/gdb-debughelpers.py index d16450bc6d2e..047a229b982c 100644 --- a/substratevm/debug/gdbpy/gdb-debughelpers.py +++ b/substratevm/debug/gdbpy/gdb-debughelpers.py @@ -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") @@ -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: @@ -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' - adr_str({hex(adr(obj))}) = {result}') @@ -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' - cast_to({hex(adr(obj))}, {t})') if t.code != gdb.TYPE_CODE_PTR: @@ -451,7 +454,7 @@ def cast_to(cls, obj: gdb.Value, t: gdb.Type) -> gdb.Value: trace(f' - 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: @@ -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 = [ diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java index 1ae3c4217fb2..f012843e1910 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debugentry/DebugInfoBase.java @@ -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. * @@ -167,15 +167,19 @@ 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. */ @@ -183,11 +187,11 @@ public abstract class DebugInfoBase { /** * 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}. */ @@ -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. @@ -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. */ - 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(); @@ -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() { diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java index 4cb38abb7897..2c7be7251690 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/debuginfo/DebugInfoProvider.java @@ -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. * @@ -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. @@ -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(); diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java index 25f7e88379e9..e38565863930 100644 --- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java +++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/dwarf/DwarfInfoSectionImpl.java @@ -1133,7 +1133,7 @@ private int writeClassType(DebugContext context, ClassEntry classEntry, byte[] b abbrevCode = AbbrevCode.INDIRECT_POINTER; log(context, " [0x%08x] <1> Abbrev Number %d", pos, abbrevCode.ordinal()); pos = writeAbbrevCode(abbrevCode, buffer, pos); - int oopReferenceSize = dwarfSections.oopReferenceSize(); + int oopReferenceSize = dwarfSections.referenceSize(); log(context, " [0x%08x] byte_size 0x%x", pos, oopReferenceSize); pos = writeAttrData1((byte) oopReferenceSize, buffer, pos); layoutOffset = getIndirectLayoutIndex(classEntry); @@ -1170,7 +1170,7 @@ private int writeInterfaceType(DebugContext context, InterfaceClassEntry interfa abbrevCode = AbbrevCode.INDIRECT_POINTER; log(context, " [0x%08x] <1> Abbrev Number %d", pos, abbrevCode.ordinal()); pos = writeAbbrevCode(abbrevCode, buffer, pos); - int byteSize = dwarfSections.oopReferenceSize(); + int byteSize = dwarfSections.referenceSize(); log(context, " [0x%08x] byte_size 0x%x", pos, byteSize); pos = writeAttrData1((byte) byteSize, buffer, pos); layoutOffset = getIndirectLayoutIndex(interfaceClassEntry); @@ -1504,7 +1504,7 @@ private int writeArrayTypes(DebugContext context, ArrayTypeEntry arrayTypeEntry, abbrevCode = AbbrevCode.INDIRECT_POINTER; log(context, " [0x%08x] <1> Abbrev Number %d", pos, abbrevCode.ordinal()); pos = writeAbbrevCode(abbrevCode, buffer, pos); - int byteSize = dwarfSections.oopReferenceSize(); + int byteSize = dwarfSections.referenceSize(); log(context, " [0x%08x] byte_size 0x%x", pos, byteSize); pos = writeAttrData1((byte) byteSize, buffer, pos); log(context, " [0x%08x] type (pointer) 0x%x (%s)", pos, indirectLayoutOffset, name); @@ -1878,136 +1878,85 @@ public int writeIndirectOopConversionExpression(boolean isHub, byte[] buffer, in * n.b. * * The setting for option -H:+/-SpawnIsolates is determined by useHeapBase == true/false. + * The setting for option -H:+/-UseCompressedReferences is determined by compressionShift > + * 0. * */ boolean useHeapBase = dwarfSections.useHeapBase(); - int oopCompressShift = dwarfSections.oopCompressShift(); - int oopTagsShift = dwarfSections.oopTagsShift(); - int oopAlignShift = dwarfSections.oopAlignShift(); - /* we may be able to use a mask or a right shift then a left shift or just a left shift */ - int mask = 0; - int rightShift = 0; - int leftShift = 0; - int exprSize = 0; + int reservedBitsMask = dwarfSections.reservedBitsMask(); + int numReservedBits = dwarfSections.numReservedBits(); + int compressionShift = dwarfSections.compressionShift(); + int numAlignmentBits = dwarfSections.numAlignmentBits(); /* * First we compute the size of the locexpr and decide how to do any required bit-twiddling + * + * The required expression will be one of these paths: + * + * push object address ................................ (1 byte) ..... [offset] ............ + * IF reservedBitsMask != 0 ................................................................ + * . push reservedBitsMask ............................ (1 byte) ..... [offset, mask] ...... + * . NOT .............................................. (1 byte) ..... [offset, ~mask] ..... + * . AND .............................................. (1 byte) ..... [offset] ............ + * . IF numReservedBits == numAlignmentBits && compressionShift == 0 ....................... + * ... push numReservedBits ........................... (1 byte) ..... [offset, right shift] + * ... LSHR ........................................... (1 byte) ..... [offset] ............ + * ... IF compressionShift != numAlignmentBits ............................................. + * ..... push numAlignmentBits - compressionShift ..... (1 byte) ..... [offset, left shift] + * ..... LSHL ......................................... (1 byte) ..... [offset] ............ + * ... END IF .............................................................................. + * . END IF ................................................................................ + * END IF .................................................................................. + * IF useHeapBase .......................................................................... + * . IF compressionShift != 0 .............................................................. + * ... push compressionShift .......................... (1 byte) ..... [offset, left shift] + * ... LSHL ........................................... (1 byte) ..... [offset] ............ + * . END IF ................................................................................ + * . push rheap+0 ..................................... (2 bytes) .... [offset, rheap] ..... + * . ADD .............................................. (1 byte) ..... [oop] ............... + * ELSE .................................................................................... + * ................................................................... [offset == oop] ..... + * END IF .................................................................................. + * end: .............................................................. [oop] ............... */ - if (!useHeapBase) { - /* We must be compressing for a hub otherwise this call would not be needed. */ - assert isHub == true; - mask = dwarfSections.oopTagsMask(); - assert mask != 0; - /*- - * We don't need to care about zero oops just mask off the tag bits. - * - * required expression is - * - * .... push object address .. (1 byte) ..... [tagged oop] - * .... push mask ............ (1 byte) ..... [tagged oop, mask] - * .... NOT .................. (1 byte) ..... [tagged oop, ~mask] - * .... AND .................. (1 byte) ..... [raw oop] - */ - exprSize += 4; - } else { - /*- - * required expression will be one of these paths - * - * .... push object address .. (1 byte) ..... [offset] - * .... duplicate object base (1 byte) ..... [offset, offset] - * .... push 0 ............... (1 byte) ..... [offset, offset, 0] - * .... eq ................... (1 byte) ..... [offset] - * .... brtrue end ........... (3 bytes) .... [offset == oop == 0 if taken] - * IF mask != 0 - * .... push mask ............ (1 byte) ..... [offset, mask] - * .... NOT .................. (1 byte) ..... [offset, ~mask] - * .... AND .................. (1 byte) ..... [offset] - * ELSE - * IF rightShift != 0 - * .... push rightShift ...... (1 byte) ..... [offset, right shift] - * .... LSHR ................. (1 byte) ..... [offset] - * END IF - * IF leftShift != 0 - * .... push leftShift ....... (1 byte) ..... [offset, left shift] - * .... LSHL ................. (1 byte) ..... [offset] - * END IF - * END IF - * .... push rheap+0 ......... (2 bytes) .... [offset, rheap] - * .... ADD .................. (1 byte) ..... [oop] - * end: ...................................... [oop] - * - */ - /* Count all bytes in common path */ - exprSize += 10; - if (isHub) { - if (oopCompressShift == 0) { - /* We need to use oopAlignment for the shift. */ - oopCompressShift = oopAlignShift; - } - if (oopCompressShift == oopTagsShift) { - /* We can use a mask to remove the bits. */ - mask = dwarfSections.oopTagsMask(); - exprSize += 3; - } else { - /* We need one or two shifts to remove the bits. */ - if (oopTagsShift != 0) { - rightShift = oopTagsShift; - exprSize += 2; - } - leftShift = oopCompressShift; - exprSize += 2; - } - } else { - /* No flags to deal with, so we need either an uncompress or nothing. */ - if (oopCompressShift != 0) { - leftShift = oopCompressShift; - exprSize += 2; - } - } - } - /* Write size followed by the expression and check the size comes out correct. */ - pos = writeULEB(exprSize, buffer, pos); + + int lengthPos = pos; + /* + * write dummy expr length (max expression size is 10 -> 1 byte is enough) + */ + pos = writeULEB(0, buffer, pos); int exprStart = pos; - if (!useHeapBase) { - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_push_object_address, buffer, pos); - pos = writeExprOpcodeLiteral(mask, buffer, pos); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_not, buffer, pos); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_and, buffer, pos); - } else { - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_push_object_address, buffer, pos); - /* skip to end if oop is null */ - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_dup, buffer, pos); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_lit0, buffer, pos); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_eq, buffer, pos); - int skipStart = pos + 3; /* offset excludes BR op + 2 operand bytes */ - short offsetToEnd = (short) (exprSize - (skipStart - exprStart)); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_bra, buffer, pos); - pos = writeShort(offsetToEnd, buffer, pos); - /* insert mask or shifts as necessary */ - if (mask != 0) { - pos = writeExprOpcodeLiteral(mask, buffer, pos); + pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_push_object_address, buffer, pos); + if (isHub && reservedBitsMask != 0) { + if (numReservedBits == numAlignmentBits && compressionShift == 0) { + pos = writeExprOpcodeLiteral(reservedBitsMask, buffer, pos); pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_not, buffer, pos); pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_and, buffer, pos); } else { - if (rightShift != 0) { - pos = writeExprOpcodeLiteral(rightShift, buffer, pos); - pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_shr, buffer, pos); - } - if (leftShift != 0) { - pos = writeExprOpcodeLiteral(leftShift, buffer, pos); + pos = writeExprOpcodeLiteral(numReservedBits, buffer, pos); + pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_shr, buffer, pos); + if (compressionShift != numAlignmentBits) { + pos = writeExprOpcodeLiteral(numAlignmentBits - compressionShift, buffer, pos); pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_shl, buffer, pos); } } + } + if (useHeapBase) { + if (compressionShift != 0) { + pos = writeExprOpcodeLiteral(compressionShift, buffer, pos); + pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_shl, buffer, pos); + } /* add the resulting offset to the heapbase register */ pos = writeExprOpcodeBReg(dwarfSections.getHeapbaseRegister(), buffer, pos); pos = writeSLEB(0, buffer, pos); /* 1 byte. */ pos = writeExprOpcode(DwarfExpressionOpcode.DW_OP_plus, buffer, pos); - assert pos == skipStart + offsetToEnd; - - /* make sure we added up correctly */ - assert pos == exprStart + exprSize; } + + int exprSize = pos - exprStart; + assert exprSize > 0 && exprSize <= 10; + writeULEB(exprSize, buffer, lengthPos); // fixup expression length + return pos; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/ReferenceAccess.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/ReferenceAccess.java index d0d6e9f733e8..0fc4355e8d57 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/ReferenceAccess.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/ReferenceAccess.java @@ -29,7 +29,7 @@ import org.graalvm.word.Pointer; import org.graalvm.word.UnsignedWord; -import com.oracle.svm.core.config.ObjectLayout; +import com.oracle.svm.core.graal.meta.SubstrateBasicLoweringProvider; import jdk.graal.compiler.api.replacements.Fold; import jdk.graal.compiler.core.common.CompressEncoding; @@ -39,37 +39,12 @@ * Means for accessing object references, explicitly distinguishing between compressed and * uncompressed references. *

- *

- * SubstrateVM uses the following object reference variants: - *

- *

    - *
  1. -H:-SpawnIsolates (explicitly disabled isolates support) - *
      - *
    • Regular reference: address64 = val64 - *
    • Reference to hub: address64 = val64 & GC-bits_bitmask - *
    - *
    where GC-bits_bitmask is - * ~{@link ObjectHeader#getReservedBitsMask()}

    - *
  2. -H:+SpawnIsolates and -H:-UseCompressedReferences (CE default) - *
      - *
    • Regular reference: address64 = val64 + r14 - *
    • Reference to hub: - * address64 = ((val64 >>> num_GC_bits) << objectAlignmentBits) + r14 - *
    - *
    where objectAlignmentBits is defined by - * Integer.bitCount({@link ObjectLayout#getAlignment()} - 1)

    - *
  3. -H:+SpawnIsolates and -H:+UseCompressedReferences (EE default) - *
      - *
    • Regular reference: address64 = (val32 << compressShift) + r14 - *
    • Reference to hub: address64 = ((val32 >>> num_GC_bits) << compressShift) + r14 - *
      - *
    - *
    where compressShift is defined by - * {@link CompressEncoding#getShift()}
    - *
- *
- *
In 2. and 3. num_GC_bits is - * Integer.bitCount({@link ObjectHeader#getReservedBitsMask()})
+ * Accessing hub references involves the reserved GC bits, compression shift and object alignment + * and is defined by {@link SubstrateBasicLoweringProvider#createReadHub}. + * + * Regular references just require the heapbase register (for -H:+SpawnIsolates) and compression + * shift (for -H:+UseCompressedReferences) + *

*/ public interface ReferenceAccess { @Fold diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoFeature.java index 6779ef050649..7c40cd5b98bc 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoFeature.java @@ -117,13 +117,13 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerAsAccessed(ReflectionUtil.lookupField(ClassLoader.class, "nameAndId")); CompressEncoding compressEncoding = ImageSingletons.lookup(CompressEncoding.class); - CGlobalData compressedShift = CGlobalDataFactory.createWord(WordFactory.signed(compressEncoding.getShift()), "__svm_compressed_shift"); + CGlobalData compressionShift = CGlobalDataFactory.createWord(WordFactory.signed(compressEncoding.getShift()), "__svm_compression_shift"); CGlobalData useHeapBase = CGlobalDataFactory.createWord(WordFactory.unsigned(compressEncoding.hasBase() ? 1 : 0), "__svm_use_heap_base"); - CGlobalData oopTagsMask = CGlobalDataFactory.createWord(WordFactory.unsigned(Heap.getHeap().getObjectHeader().getReservedBitsMask()), "__svm_oop_tags_mask"); + CGlobalData reservedBitsMask = CGlobalDataFactory.createWord(WordFactory.unsigned(Heap.getHeap().getObjectHeader().getReservedBitsMask()), "__svm_reserved_bits_mask"); CGlobalData objectAlignment = CGlobalDataFactory.createWord(WordFactory.unsigned(ConfigurationValues.getObjectLayout().getAlignment()), "__svm_object_alignment"); - CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(compressedShift); + CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(compressionShift); CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(useHeapBase); - CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(oopTagsMask); + CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(reservedBitsMask); CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(objectAlignment); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProviderBase.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProviderBase.java index 63490a22fc2d..fdafdf2d6493 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProviderBase.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageDebugInfoProviderBase.java @@ -81,13 +81,13 @@ public abstract class NativeImageDebugInfoProviderBase { protected final NativeLibraries nativeLibs; protected final RuntimeConfiguration runtimeConfiguration; protected final boolean useHeapBase; - protected final int compressShift; + protected final int compressionShift; protected final int referenceSize; protected final int pointerSize; - protected final int referenceAlignment; + protected final int objectAlignment; protected final int primitiveStartOffset; protected final int referenceStartOffset; - protected final int tagsMask; + protected final int reservedBitsMask; protected final HostedType hubType; protected final HostedType wordBaseType; @@ -105,17 +105,17 @@ public NativeImageDebugInfoProviderBase(NativeImageCodeCache codeCache, NativeIm ObjectHeader objectHeader = Heap.getHeap().getObjectHeader(); NativeImageHeap.ObjectInfo primitiveFields = heap.getObjectInfo(StaticFieldsSupport.getStaticPrimitiveFields()); NativeImageHeap.ObjectInfo objectFields = heap.getObjectInfo(StaticFieldsSupport.getStaticObjectFields()); - this.tagsMask = objectHeader.getReservedBitsMask(); + this.reservedBitsMask = objectHeader.getReservedBitsMask(); if (SubstrateOptions.SpawnIsolates.getValue()) { CompressEncoding compressEncoding = ImageSingletons.lookup(CompressEncoding.class); this.useHeapBase = compressEncoding.hasBase(); - this.compressShift = (compressEncoding.hasShift() ? compressEncoding.getShift() : 0); + this.compressionShift = (compressEncoding.hasShift() ? compressEncoding.getShift() : 0); } else { this.useHeapBase = false; - this.compressShift = 0; + this.compressionShift = 0; } this.referenceSize = getObjectLayout().getReferenceSize(); - this.referenceAlignment = getObjectLayout().getAlignment(); + this.objectAlignment = getObjectLayout().getAlignment(); /* Offsets need to be adjusted relative to the heap base plus partition-specific offset. */ primitiveStartOffset = (int) primitiveFields.getOffset(); referenceStartOffset = (int) objectFields.getOffset(); @@ -369,11 +369,11 @@ public boolean useHeapBase() { return useHeapBase; } - public int oopCompressShift() { - return compressShift; + public int compressionShift() { + return compressionShift; } - public int oopReferenceSize() { + public int referenceSize() { return referenceSize; } @@ -381,12 +381,12 @@ public int pointerSize() { return pointerSize; } - public int oopAlignment() { - return referenceAlignment; + public int objectAlignment() { + return objectAlignment; } - public int oopTagsMask() { - return tagsMask; + public int reservedBitsMask() { + return reservedBitsMask; } public int compiledCodeMax() {