On Fri, 8 Apr 2022 08:13:33 GMT, Thomas Schatzl <tscha...@openjdk.org> wrote:

> Hi all,
> 
>   can I have reviews for this change that adds dedicated filler objects to 
> the VM?
> 
> Currently, when formatting areas of dead objects all gcs use instances of 
> j.l.Object and int-arrays.
> 
> This has the drawback of not being easily able to discern whether a given 
> object is actually dead (and should never be referenced) or just a regular 
> j.l.Object/int array.
> 
> This also makes enhanced error detection (any reference to such an object is 
> an error - i.e. detecting references to such objects) and to skip potentially 
> already unloaded classes when scanning areas of the heap below TAMS, G1 uses 
> its prev bitmap.
> Other collectors do not have this extra information at the moment, so they 
> can't (and don't) do this kind of verification.
> 
> With [JDK-8210708](https://bugs.openjdk.java.net/browse/JDK-8210708) the prev 
> bitmap will effectively be removed in G1; G1 will format the dead areas with 
> these filler objects to avoid coming across unloaded classes. This is fine 
> wrt to normal operation, however, this looses the existing enhanced 
> verification mentioned above.
> 
> This change proposes to add dedicated VM-internal filler objects, i.e. 
> equivalents of j.l.Object and int-arrays.
> 
> This has the following benefits:
> 
> - keep this error detection (actually making it much simpler) and allowing 
> similar verification for other collectors. (This change does not add this)
> 
> - this also makes it "easy" to detect references to filler objects in 
> debugging tools - you only need to know the two klasses (or just get their 
> friendly name) to see whether that reference may actually be valid (or refers 
> to the inside such an object). References to these classes in the crash file 
> may also allow the issue to be more clear.
> 
> This causes some minor changes to external behavior:
> 
> - logs/heap dumps now contain instances of these objects - which seems fine 
> as previously they have just been reported as part of j.l.Object/int-arrays 
> statistics. The VM spec also does not guarantee whether a particular kind of 
> object should/should not show there anyway afaik.
> 
> - if the application ever gets to instantiate a reference to such an object 
> somehow, any enabled verification will crash the VM. That's bad luck for 
> messing with internal classes, but that's the purpose of these objects.
> 
> The change takes care that getting a reference will not be possible by normal 
> means (i.e. via Class.forName() etc) - which should be sufficient to avoid 
> the issue. Actually, existing mechanisms seem to be sufficient.
> 
> 
> Testing: tier1-8
> 
> There is one question I would like the reviewers to specially think about, 
> the name of the filler array klass. I just used 
> `Ljava/internal/vm/FillerArray;` for that, looking at other internal 
> symbols/klasses, but I'm not sure this adheres to naming guidelines.
> 
> Thanks go to @iklam for helping out with the change.
> 
> Thanks,
>   Thomas

Changes requested by iklam (Reviewer).

src/hotspot/share/classfile/systemDictionaryShared.cpp line 1727:

> 1725:     ArchivedMirrorPatcher::update_array_klasses(k);
> 1726:   }
> 1727:   
> ArchivedMirrorPatcher::update_array_klasses(Universe::fillerArrayKlassObj());

I think this is not necessary. `Universe::fillerArrayKlassObj()` shares the 
same mirror as `Universe::intArrayKlassObj()`, which has already been updated 
in the loop above.

`ArchivedMirrorPatcher::update_array_klasses(k)` will essentially do 
`k->mirror->pointer_back_to_klass += delta`, so it will incorrectly set the 
pointer when delta is not zero.

I would suggest running with


-XX:ArchiveRelocationMode=1 -Xlog:cds -Xlog:class+load=debug


and step into the following code: 


void java_lang_Class::update_archived_mirror_native_pointers(oop 
archived_mirror) {
  assert(MetaspaceShared::relocation_delta() != 0, "must be");

  Klass* k = ((Klass*)archived_mirror->metadata_field(_klass_offset));
  archived_mirror->metadata_field_put(_klass_offset,
      (Klass*)(address(k) + MetaspaceShared::relocation_delta())); <<<< HERE

src/hotspot/share/memory/universe.cpp line 205:

> 203:   }
> 204:   // Hide _fillerArrayKlassObj from JVMTI
> 205:   // closure->do_klass(_fillerArrayKlassObj);

Maybe the comment should be more explicit?

// We don't do the following because it will confuse JVMTI.
// _fillerArrayKlassObj is used only by GC, which doesn't need to see 
// this klass from basic_type_classes_do().

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

PR: https://git.openjdk.java.net/jdk/pull/8156

Reply via email to