accessing unknown value type element in Object[] array & GC barriers

David Simms david.simms at oracle.com
Fri Aug 31 14:09:14 UTC 2018


Hi Roland, sorry for the delayed reply...

I doubled checked, you are correct, that ZGC does not use the clone 
intrinsic. Going forward it will, but on TODO list just now.

"ValueKlass::value_store()" currently issues write barrier for 
traditional GCs, and mostly ignores the Access API. ZGC is (will be) 
disabled in the prototype...but LW10 will need it. Current hack is 
"BarrierSet::write_ref_array_pre", then copy, then 
"BarrierSet::write_ref_array()"


For read barriers...

I'm hoping to get some time to discuss additions to the Access API 
specifically for value types.

Yeah are correct that clone, array store/load to/from heap buffer (i.e. 
an oop) and loading fields from heap buffered value types all have 
similar problems. First the source oop when reading from heap buffer 
(i.e. i2c) will need a read barrier, then the contents need read barrier 
at their use time, which for array store (and copy) would be immediately 
before store.

The size of the actual element payload in flatten array is the same as 
the instance...but the addressing is power of 2, so the "element size" 
may contain some padding which we don't touch.

/D


On 29/08/18 14:02, Roland Westrelin wrote:
> A question for someone familiar with GC barriers below...
>
> Currently for:
>
> Object array_load(Object[] array) {
>    return array[0];
> }
>
> we roughly emit:
>
> Object array_load(Object[] array) {
>    if (is_flattened(array)) { deoptimize(); }
>    return array[0];
> }
>
> Same thing for:
>
> void array_store(Object[] array, Object o) {
>    array[0] = o;
> }
>
> roughly emitted as:
>
> void array_store(Object[] array, Object o) {
>    if (is_flattened(array)) { deoptimize(); }
>    array[0] = o;
> }
>
> Instead we would want:
>
> Object array_load(Object[] array) {
>    Object v;
>    if (is_flattened(array)) {
>      v = array.getComponentType().newInstance();
>      copy(v, array[0]);
>    } else {
>      v = array[0];
>    }
>    return v;
> }
>
> The first if branch is similar to the clone intrinsic (we're not copying
> from an instance but from some flattened array element) so reusing that
> machinery is possible (and prototyped). The problem here is that if the
> unknown value has oop fields, depending on the gc, barriers might be
> needed. In its current state ZGC doesn't support the clone intrinsic and
> so we wouldn't support the pattern above with ZGC either.
>
> void array_store(Object[] array, Object o) {
>    if (is_flattened(array)) {
>      copy(array[0], o);
>      post_barrier();
>    } else {
>      array[0] = o;
>    }
> }
>
> Again somewhat similar to the clone intrinsic but copy is not to a newly
> allocated object so we need a barrier. C2 has some support for non
> precise post barrier but I'm unclear what to pass to that barrier for
> serial/parallel/CMS or G1: the array oop? &array[0]? Are there cases
> where several cards need to be marked?
>
> Other unrelated question: how does the size of the element of a
> flattened array compare to the size of value instance? Do they differ or
> can we use either one interchangeably?
>
> Roland.





More information about the valhalla-dev mailing list