RFR: Eliminate extra forwarding pointer per object
rkennke at redhat.com
Tue May 7 15:59:40 UTC 2019
Until now, Shenandoah had the 'limitation' that it required an extra
word per object to keep the forwarding pointer. It either points to
itself (most of the time) or to the forwarded object when evacuated. The
forwarding pointer is updated atomically using CAS. This is the heart of
Shenandoah's evacuation protocol.
With LRB, we have the opportunity to eliminate that extra word. The
insight is that we really don't need the old copy of an object anymore
and we can store the forwarding pointer in the mark word of it. We would
distinguish a valid mark word from a forwarding pointer by checking the
lowest 2 bits: if they are 0b11 then it's forwarded, otherwise it's not.
0b11 is not a valid combination of bits otherwise. This is the same
protocol that is used by other GCs.
The evacuation protocol changes slightly to CAS into the mark word
instead of the extra word. But the basic mechanics are the same.
The extra decoding does not (significantly) affect performance because
it's only done in the mid/slow-path of the LRB. (As opposed to earlier
attempts at it where it'd have to be in the read-barrier.)
I've run SPECjvm2008. Performance benefits vary between 0 and ~+10%. One
exception is one of the scimarks which is negatively impacted. The
reason appears to be that this benchmark is very heavily contended on
synchronizer objects, and the tighter spacing negatively impacts it when
running with many threads. I don't consider this a true regression.
SPECjbb2015 shows +12% improvement in throughput and +9% improvement in
I propose to push it to shenandoah/jdk and bake it there a little before
upstreaming it into jdk/jdk.
Testing: hotspot_gc_shenandoah (x86,aarch64) specjvm, specjbb, most of
them many many times
More information about the shenandoah-dev