RFR(M): 8130847: Cloned object's fields observed as null after C2 escape analysis

Vladimir Kozlov vladimir.kozlov at oracle.com
Tue Jul 28 22:42:08 UTC 2015


I misread assert's message - I thought "only arraycopy which modifies an 
allocate makes it escape". Have to read more carefully.

Wait, original code looks buggy - 'mem' is set to input memory 
regardless may_modify() result:

!         if (!call->may_modify(tinst, phase)) {
!           mem = call->in(TypeFunc::Memory);
           }
           mem = in->in(TypeFunc::Memory);

That is what got my attention. Your change looks fine in this code - we 
skip all call nodes except arraycopy which modifies this field/element. 
And we can skip all calls because we are processing non-escaping allocation.

Thanks,
Vladimir

On 7/28/15 11:26 AM, Roland Westrelin wrote:
> Thanks for looking at this, Vladimir.
>
>> The next change puzzles me:
>>
>> -         if (!call->may_modify(tinst, phase)) {
>> +         if (call->may_modify(tinst, phase)) {
>> -           mem = call->in(TypeFunc::Memory);
>> +           assert(call->is_ArrayCopy(), "ArrayCopy is the only call node that doesn't make allocation escape");
>>
>> Why only ArrayCopy? I think it is most of calls. What set of tests you ran?
>
> I ran:
>
> java/lang, java/util, compiler, closed, runtime, gc jtreg tests
> nsk.stress, vm.compiler, vm.regression, nsk.regression, nsk.monitoring from ute
> jprt
>
> I’m not sure if I did CTW or not but I can if you think it makes sense.
>
> Aren’t arguments of calls marked as ArgEscape so an object that is an argument to a call cannot be scalar replaced?
>
>> Methods naming is confusing. membar_for_arraycopy() does not check for membar but for calls which can modify. handle_arraycopy() could be make_arraycopy_load().
>>
>> Add explicit check:
>> && strcmp(_name, "unsafe_arraycopy") != 0)
>
> Thanks for the suggestions. I’ll make the suggested changes.
>
> Roland.
>
>>
>> Thanks,
>> Vladimir
>>
>> On 7/28/15 7:05 AM, Roland Westrelin wrote:
>>> http://cr.openjdk.java.net/~roland/8130847/webrev.00/
>>>
>>> When an allocation which is the destination of an ArrayCopyNode is eliminated, field’s values recorded at a safepoint (to reallocate the object) do not take the ArrayCopyNode into account at all and the effect or the ArrayCopyNode is lost on a deoptimization. This fix records values from the source of the ArrayCopyNode, emitting new loads if necessary.
>>>
>>> I also use the opportunity to pin the loads generated in LoadNode::can_see_arraycopy_value() because they depend on all checks that validate the array copy and not only on the check that immediately dominates.
>>>
>>> Roland.
>>>
>


More information about the hotspot-compiler-dev mailing list