RFR: 8305895: Implement JEP 450: Compact Object Headers (Experimental) [v13]

Thomas Stuefe stuefe at openjdk.org
Sun Sep 15 06:17:14 UTC 2024


On Wed, 11 Sep 2024 21:15:21 GMT, Coleen Phillimore <coleenp at openjdk.org> wrote:

>> Roman Kennke has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Revert accidental change of UCOH default
>
> I was starting to understand the concerns with having prototype_header in Klass.  It seems like it would simplify encoding the klass for object allocation.  My recent change https://bugs.openjdk.org/browse/JDK-8338526 breaks this.  You need to pass a parameter to Klass() to tell whether to encode the klass pointer or not, and pass this to Klass() constructor.
> 
>      diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
>      index fd198f54fc9..7aa4bd24948 100644
>      --- a/src/hotspot/share/oops/instanceKlass.cpp
>      +++ b/src/hotspot/share/oops/instanceKlass.cpp
>     @@ -511,7 +511,7 @@ InstanceKlass::InstanceKlass() {
>      }
>      
>      InstanceKlass::InstanceKlass(const ClassFileParser& parser, KlassKind kind, ReferenceType reference_type) :
>     -  Klass(kind),
>     +  Klass(kind, (!parser.is_interface() && !parser.is_abstract())),
>        _nest_members(nullptr),
>        _nest_host(nullptr),
>        _permitted_subclasses(nullptr),

@coleenp 

> I was starting to understand the concerns with having prototype_header in Klass. It seems like it would simplify encoding the klass for object allocation. My recent change https://bugs.openjdk.org/browse/JDK-8338526 breaks this. You need to pass a parameter to Klass() to tell whether to encode the klass pointer or not, and pass this to Klass() constructor.
> 

I solved this differently (Roman will merge this into his PR).


static markWord make_prototype(const Klass* kls) {
  markWord prototype = markWord::prototype();
#ifdef _LP64
  if (UseCompactObjectHeaders) {
    // With compact object headers, the narrow Klass ID is part of the mark word.
    // We therfore seed the mark word with the narrow Klass ID.
    // Note that only those Klass that can be instantiated have a narrow Klass ID.
    // For those who don't, we leave the klass bits empty and assert if someone
    // tries to use those.
    const narrowKlass nk = CompressedKlassPointers::is_encodable(kls) ?
        CompressedKlassPointers::encode(const_cast<Klass*>(kls)) : 0;
    prototype = prototype.set_narrow_klass(nk);
  }
#endif
  return prototype;
}

inline bool CompressedKlassPointers::is_encodable(const void* address) {
  check_init(_base);
  // An address can only be encoded if:
  //
  // 1) the address lies within the klass range.
  // 2) It is suitably aligned to 2^encoding_shift. This only really matters for
  //    +UseCompactObjectHeaders, since the encoding shift can be large (max 10 bits -> 1KB).
  return is_aligned(address, klass_alignment_in_bytes()) &&
      address >= _klass_range_start && address < _klass_range_end;
}


So, we put an nKlass into the prototype if we can. We can, if the Klass address is encodable. It is encodable if it lives in the encoded Klass range and is correctly aligned. No need to pass this information via another channel: its right there, in the Klass address. This works even before Klass is initialized.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/20677#issuecomment-2351399143


More information about the build-dev mailing list