RFR(S): ZGC: C2: Oop instance cloning causing skipped compiles
Vladimir Ivanov
vladimir.x.ivanov at oracle.com
Tue Nov 26 12:02:06 UTC 2019
> http://cr.openjdk.java.net/~neliasso/8234520/webrev.03/
====================================================================
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp:
+ // The currently modeled arraycopy-clone_basic doesn't have the base
pointers for src and dst,
+ // rather point at the start of the payload.
+ Node* src_base = get_base_for_arracycopy_clone(phase, src);
+ Node* dst_base = get_base_for_arracycopy_clone(phase, dst);
+
+ // The size must also be increased to match the instance size.
+ int base_off = BarrierSetC2::extract_base_offset(false);
+ Node* full_size = phase->transform_later(new AddLNode(size,
phase->longcon(base_off >> LogBytesPerLong)));
Node* const call = phase->make_leaf_call(ctrl,
mem,
clone_type(),
ZBarrierSetRuntime::clone_addr(),
"ZBarrierSetRuntime::clone",
TypeRawPtr::BOTTOM,
- src,
- dst,
- size);
+ src_base,
+ dst_base,
+ full_size,
+ phase->top());
Do you see any problems with copying object header?
====================================================================
The rest are minor comments:
src/hotspot/share/gc/shared/c2/barrierSetC2.cpp:
-void BarrierSetC2::clone(GraphKit* kit, Node* src, Node* dst, Node*
size, bool is_array) const {
- // Exclude the header but include array length to copy by 8 bytes words.
- // Can't use base_offset_in_bytes(bt) since basic type is unknown.
+int BarrierSetC2::extract_base_offset(bool is_array) {
...
+void BarrierSetC2::clone(GraphKit* kit, Node* src, Node* dst, Node*
size, bool is_array) const {
+ // Exclude the header but include array length to copy by 8 bytes words.
+ // Can't use base_offset_in_bytes(bt) since basic type is unknown.
+ int base_off = extract_base_offset(is_array);
I'd leave the comment in BarrierSetC2::extract_base_offset(). After the
refactoring it looks confusing in BarrierSetC2::clone().
Also, considering it's used from zBarrierSetC2.cpp, it would be nice to
have a more descriptive name.
BarrierSetC2::arraycopy_payload_base_offset(bool is_array) maybe?
====================================================================
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp:
+Node* get_base_for_arracycopy_clone(PhaseMacroExpand* phase, Node* n) {
Should get_base_for_arracycopy_clone be static? Also, would be nice if
the name reflects that it works on instances and not arrays.
====================================================================
+ // The currently modeled arraycopy-clone_basic doesn't have the base
pointers for src and dst,
+ // rather point at the start of the payload.
+ Node* src_base = get_base_for_arracycopy_clone(phase, src);
+ Node* dst_base = get_base_for_arracycopy_clone(phase, dst);
Another thing: "base" in zBarrierSetC2.cpp and in BarrierSetC2 has
opposite meaning which is confusing.
Renaming src/dst<->src_base/dst_base in
ZBarrierSetC2::clone_at_expansion() would improve things.
====================================================================
- if (src->bottom_type()->isa_aryptr()) {
+ if (ac->is_clone_array()) {
// Clone primitive array
Is the comment valid? Doesn't it cover object array case as well?
Best regards,
Vladimir Ivanov
>
> Regards,
>
> Nils
>
>
> On 2019-11-21 12:53, Nils Eliasson wrote:
>> I updated this to version 2.
>>
>> http://cr.openjdk.java.net/~neliasso/8234520/webrev.02/
>>
>> I found a problen running
>> compiler/arguments/TestStressReflectiveCode.java
>>
>> Even though the clone was created as a oop clone, the type node type
>> returns isa_aryprt. This is caused by the src ptr not being the base
>> pointer. Until I fix that I wanted a more robust test.
>>
>> In this webrev I split up the is_clonebasic into is_clone_oop and
>> is_clone_array. (is_clone_oop_array is already there). Having a
>> complete set with the three clone types allows for a robust test and
>> easy verification. (The three variants end up in different paths with
>> different GCs).
>>
>> Regards,
>>
>> Nils
>>
>>
>> On 2019-11-20 15:25, Nils Eliasson wrote:
>>> Hi,
>>>
>>> I found a few bugs after the enabling of the clone intrinsic in ZGC.
>>>
>>> 1) The arraycopy clone_basic has the parameters adjusted to work as a
>>> memcopy. For an oop the src is pointing inside the oop to where we
>>> want to start copying. But when we want to do a runtime call to clone
>>> - the parameters are supposed to be the actual src oop and dst oop,
>>> and the size should be the instance size.
>>>
>>> For now I have made a workaround. What should be done later is using
>>> the offset in the arraycopy node to encode where the payload is, so
>>> that the base pointers are always correct. But that would require
>>> changes to the BarrierSet classes of all GCs. So I leave that for
>>> next release.
>>>
>>> 2) The size parameter of the TypeFunc for the runtime call has the
>>> wrong type. It was originally Long but missed the upper Half, it was
>>> fixed to INT (JDK-8233834), but that is wrong and causes the compiles
>>> to be skipped. We didn't notice that since they failed silently. That
>>> is also why we didn't notice problem #1 too.
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8234520
>>>
>>> http://cr.openjdk.java.net/~neliasso/8234520/webrev.01/
>>>
>>> Please review!
>>>
>>> Nils
>>>
More information about the hotspot-compiler-dev
mailing list