On Thu, 7 Apr 2022 18:28:42 GMT, Roman Kennke <[email protected]> wrote:
>> JVMTI heap walking marks objects in order to track which have been visited
>> already. In order to do that, it uses bits in the object header. Those are
>> the same bits that are also used by some GCs to mark objects (the lowest two
>> bits, also used by locking code). Some GCs also use the bits in order to
>> indicate 'forwarded' objects, where the upper bits of the header represent
>> the forward-pointer. In the case of Shenandoah, it's even more problematic
>> because this happens concurrently, even while JVMTI heap walks can
>> intercept. So far we carefully worked around that problem, but it becomes
>> very problematic in Lilliput, where accesses to the Klass* also requires to
>> decode the header, and figure out what bits means what.
>>
>> In addition to that, marking objects in their header requires that the
>> original header gets saved and restored. We only do that for 'interesting'
>> headers, that is headers that have a stack-lock, monitor or hash-code. All
>> other headers are reset to their default value. This means we are losing
>> object's GC age. This is not catastrophic, but nontheless interferes with
>> GC.
>>
>> JFR already has a datastructure called BitSet to support object marking
>> without messing with object's headers. We can use that in JVMTI too.
>>
>> Testing:
>> - [x] tier1
>> - [x] tier2
>> - [x] tier3
>> - [x] serviceability/jvmti
>> - [x] vmTestbase/nsk/jvmti
>
> Roman Kennke has updated the pull request incrementally with one additional
> commit since the last revision:
>
> Move JFRBitSet typedef into its own header; Make _bitset a direct member,
> not dynamically allocated
> > We must call new on it somewhere. I am not opposed to making this an
> > mtFlags template then. This is a small point in this improvement.
>
> Yes, at some point we need to allocate the fragments and fragments table. We
> could _perhaps_ work around it by passing MEMFLAGS as constexpr, but I don't
> think this would change generated code much.
(all bikeshedding since we all agree the current version is fine, no?)
No, sorry, I meant make BitSet a normal class. Not derived from CHeapObj, since
it gets not newed, only used via composition or on a stack. And give it a
runtime parm to set the MEMFLAG.
So:
class BitSet {
const MEMFLAGS _flags;
public:
BitSet(MEMFLAGS f = mtInternal) : _flags(f) {...}
};
and use those flags for the c-heap allocation of the fragments.
-------------
PR: https://git.openjdk.java.net/jdk/pull/7964