RFR(S): 8224580: Matcher can cause oop field/array element to be reloaded

Roland Westrelin rwestrel at redhat.com
Wed May 22 08:55:18 UTC 2019


With Shenandoah, we have a prototype where, rather than using an extra
header field for the forwarding pointer, we use the mark word. When the
shenandoah barrier is applied to an oop, the oop is first checked to be
in cset which is done by converting the oop to an integer and extracting
some of the bits of the address and then, if that test fails, the
forwarding pointer is loaded by masking off some bits in the mark
word. We're seeing a case where, in compiled code, the in cset test and
the mark word load for the same oop use 2 different loads, i.e. the load
of the field/array element is duplicated, the oop is reloaded between
the in cset test and loading of the forwarding pointer. This only with
compressed oops.

I traced it down to the matcher, where the LoadN node for the
field/array element is not marked as shared and so is emitted
twice. This happens because the LoadN result is only used through a
decodeN which has multiple uses. I see the matcher has code to deal with
that situation:

if( mop == Op_AddP && m->in(AddPNode::Base)->is_DecodeNarrowPtr()) {
  // Bases used in addresses must be shared but since
  // they are shared through a DecodeN they may appear
  // to have a single use so force sharing here.

But that logic doesn't trigger in our case because the mark word load is
at offset 0 so there's not AddP. The fix I propose is to always mark the
input of a DecodeN as shared if the DecodeN is shared.


More information about the hotspot-compiler-dev mailing list