RFR(M): tweak zeroing elimination to support initialization of non flattened value arrays

Roland Westrelin rwestrel at redhat.com
Tue Sep 11 12:15:16 UTC 2018


Hi Tobias,

Thanks for looking at this.

> - Could you explain the change to vm_version_x86.cpp?

In MacroAssembler::clear_mem() there are 3 ways to clear a large
array. The first one is not applicable to non flattened value arrays
(non null init value) and I suppose (but haven't measure it) that the
second one is better than the 3rd one. Without the vm_version change,
the second one would never trigger if UseFastStosb is true.

Beyond that the logic in vm_version is strange because, as I understand,
the role of vm_version_x86.cpp is to detect hardware capabilities not to
decide if it's better to use one way or another to clear an array. That
part should be left to the code that clears the array.

> - I'm a bit confused by DefaultValue and RawDefaultValue. It seems that the code in
> graphKit.cpp:4051 only sets RawDefaultValue but there are asserts that check that if DefaultValue is
> not set, RawDefaultValue should not be set either (for example, in memnode.cpp).

DefaultValue is set for non flattened value type array to the default
value (an oop or compressed oop).
RawDefaultValue is set to a 64 bit value that can be used to initialize
an array.

Ignoring reflection, DefaultValue and RawDefaultValue are either both
set or neither set.

1) RawDefaultValue is passed to ClearArray. That one takes care of doing a
bulk initialization of the array.

2) DefaultValue is used when, for instance, loading an element from a
just allocated array: then the load should return the default value.

3) There are also cases with arraycopy and store capture, with an array
of compressed oops, where the entire array can't be initialized with a
bulk ClearArray and individual 32 bit element must be set separately. In
that case DefaultValue is used.

DefaultValue and RawDefaultValue so far are largely redundant. Then
comes reflection. If an array is allocated through reflection, we don't
know the element type. It could be a non flattened value array or a pojo
array or a basic type array. DefaultValue which is an oop doesn't make
sense for a basic type array. So it's not set at all in the case of
reflection. RawDefaultValue can be set. It's zero unless it's a non
flattened array, then it's the default value casted to a 64 bit
integer. C2 in that case emits runtime checks to correctly set
RawDefaultValue.

This assumes 2) or 3) above don't trigger for an array allocated with
reflection. That's what the asserts try to catch. I tried to trigger 2)
or 3) with reflection but didn't succeed.

> - What does "coops" stand for? Maybe add a comment to that method.

compressed oops. With compressed oops, the 64 bit RawDefaultValue is
built from 2 32 bit DefaultValue.

> This solves JDK-8189802 [1], right? If so, I would suggest that you re-use this bug number.

Yes, it should.

BTW, I noticed ValueTypeNode::load_default_oop() doesn't return a
constant. But for a known value klass, the default value should be
known, right?

Roland.


More information about the valhalla-dev mailing list