System.arraycopy

Tom Rodriguez tom.rodriguez at oracle.com
Mon Jun 9 22:27:34 UTC 2014


On Jun 9, 2014, at 8:24 AM, Deneau, Tom <tom.deneau at amd.com> wrote:

> I did some tweaking to our HSAILHotSpotReplacementsImpl to basically make it always use the non-foreign-call version (UnsafeArrayCopy) rather than the foreign-call version, regardless of the sense of the global flag CallArrayCopy.  This seems to  cover most of the arraycopy cases.
> 
> The one case that this not handle is a "non-exact" Object Array copy, for instance copying and array of Strings to an array of Objects.

That case could be handled with the existing code by improving the store check.  Currently it tests that the hubs are equal but for arrays the requirement is really that the element type of the destination is assignable from the source element type.  So copying from String[] to Object[] doesn’t require any per element checks but the reverse operation does.  UnsafeArrayCopyNode doesn’t do that great a job of decomposing the interesting cases for Object copies.  Also the generic code doesn’t handle conjoint copies either which is fairly common.

> 
> I see the snippet code for this "generic array copy" does as shown below and I believe we are taking the genericObjectCallCounter path.  So we still fail with
> 
>  com.oracle.graal.graph.GraalGraphInternalError com.oracle.graal.compiler.common.GraalInternalError: unimplemented
> 	at node: 78|Invoke#Direct#System.arraycopy
> 
> (I guess this doesn't get replaced by a snippet since it is already in a snippet?
> 
> So my question is:  Is there any java implementation of this path?  Or any solution that would not involve a foreign call, etc.

A full implementation of array copy isn’t that hard in Java but it will entail a large amount of code.  Would it be possible call HSAIL stubs for doing the copies or does everything have to be inline?

tom 

> 
> -- Tom
> 
> =================
>    @Snippet
>    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
>        Object nonNullSrc = guardingNonNull(src);
>        Object nonNullDest = guardingNonNull(dest);
>        Word srcHub = loadHub(nonNullSrc);
>        Word destHub = loadHub(nonNullDest);
>        if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
>            int layoutHelper = checkArrayType(srcHub);
>            final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0);
> 
>            checkLimits(nonNullSrc, srcPos, nonNullDest, destPos, length);
>            if (probability(FAST_PATH_PROBABILITY, isObjectArray)) {
>                genericObjectExactCallCounter.inc();
>                UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, Kind.Object);
>            } else {
>                genericPrimitiveCallCounter.inc();
>                UnsafeArrayCopyNode.arraycopyPrimitive(nonNullSrc, srcPos, nonNullDest, destPos, length, layoutHelper);
>            }
>        } else {
>            genericObjectCallCounter.inc();
>            System.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length);
>        }
>    }
> 
> 
>> -----Original Message-----
>> From: Deneau, Tom
>> Sent: Thursday, June 05, 2014 6:29 PM
>> To: 'Tom Rodriguez'
>> Cc: Chris Thalinger; graal-dev at openjdk.java.net
>> Subject: RE: System.arraycopy
>> 
>> Using -G:-CallArrayCopy seemed to work...
>> 
>>> -----Original Message-----
>>> From: Tom Rodriguez [mailto:tom.rodriguez at oracle.com]
>>> Sent: Thursday, June 05, 2014 4:44 PM
>>> To: Deneau, Tom
>>> Cc: Chris Thalinger; graal-dev at openjdk.java.net
>>> Subject: Re: System.arraycopy
>>> 
>>> 
>>> On Jun 5, 2014, at 2:39 PM, Deneau, Tom <tom.deneau at amd.com> wrote:
>>> 
>>>> Christian --
>>>> 
>>>> For now just going for functionally correct, will address
>>>> performance
>>> issues in the future.  But yes there are vector instructions that
>>> could help even in a single workitem.
>>>> 
>>>> Is there already a pure java implementation of System.arrayCopy we
>>> could substitute?
>>> 
>>> UnsafeArrayCopyNode is pretty much that.  The flag CallArrayCopy
>>> controls whether it prefers the hotspot stubs for array copy or not
>>> but it should be able to fall back to UnsafeArrayCopyNode.
>>> 
>>> tom
>>> 
>>>> 
>>>> I guess we would want to use the logic to do different substitutions
>>> based on the type of the array (like in ArrayCopySnippets)?
>>>> 
>>>> any other advice for implementing this?
>>>> 
>>>> -- Tom
>>>> 
>>>> 
>>>> 
>>>>> -----Original Message-----
>>>>> From: Christian Thalinger [mailto:christian.thalinger at oracle.com]
>>>>> Sent: Thursday, June 05, 2014 3:45 PM
>>>>> To: Deneau, Tom
>>>>> Cc: graal-dev at openjdk.java.net
>>>>> Subject: Re: System.arraycopy
>>>>> 
>>>>> Well, I guess the easiest but maybe not most performant way would
>>>>> be to have a substitution and implement it in plain Java.
>>>>> 
>>>>> On the other hand you could rely on vectorization and the power of
>>>>> GPUs to produce good, parallel code :-)
>>>>> 
>>>>> On Jun 5, 2014, at 1:29 PM, Deneau, Tom <tom.deneau at amd.com> wrote:
>>>>> 
>>>>>> Since we cannot handle "foreign calls" in the hsail backend, what
>>>>>> is
>>>>> the preferred way to implement System.arraycopy?  Right now, we are
>>>>> deferring to the host and so getting an ArrayCopyCallNode which
>>>>> gets lowered to a graph containing a ForeignCallNode.
>>>>>> 
>>>>>> I confess to being a little confused with the ArrayCopyNode and
>>>>> Snippets, UnsafeArrayCopyNode and Snippets, ArrayCopyCallNode, etc.
>>>>>> 
>>>>>> -- Tom
>>>>>> 
>>>> 
> 



More information about the graal-dev mailing list