Unsafe.{get,put}-X-Unaligned; Efficient array comparison intrinsics

John Rose john.r.rose at oracle.com
Tue Mar 3 20:48:12 UTC 2015

On Mar 2, 2015, at 11:30 AM, Andrew Haley <aph at redhat.com> wrote:
> On 02/25/2015 04:43 PM, Andrew Haley wrote:
> I have done this as much as is possible, but methods which assemble
> and split sub-words are necessarily endian-dependent.  I have
> separated the native big- and little-endian code into two classes,
> only one of which will ever be loaded into a system.

Here is a way to merge the twin classes, using gated "pick" operators:

If merging them actually works, then the merged result should be
folded back into Unsafe, and static variables used everywhere.
I think this is better than quasi-duplicate code, if it optimizes right.

(The JIT optimizer should commute shift-mask and reversal intrinsics
to get the same result, but it doesn't at present; explicit pick is second-best.)

>>> Suggestion:  Have getIntUnaligned take an optional boolean
>>> parameter, which is "bigEndian" (since that's relatively exceptional).
>>> An extra line of code can conditionally swap the bytes, taking
>>> both the flag and the platform into account.  Default value of the
>>> boolean is whatever is natural to the platform.  If you specifically
>>> want Java's big-endian order, you specify true, etc.
> I've done this in Java.  I tried some HotSpot intrinsic code to handle
> the "bigEndian" parameter but foundered when I noticed that
> Op_ReverseBytesXX nodes are optional, so an intrinsic might either be
> emitted as an instruction or a call to a native method.  This was all
> too messy so I reverted to doing it in Java; the code quality does not
> seem to suffer as a result of this.  (Another possibility is to define
> intrinsics which would only be used if Op_ReverseBytesXX nodes were
> supported, but I don't know that such an intrinsic would buy us
> anything.)

I'm surprised it backed off to a native method.  It should have backed
off to bytecode equivalent to what you wrote (see Integer.java for the code).

> It wasn't clear to me whether you might also want set-XX-Unaligned
> methods with specific endianness, so I didn't write any.

That's fine; it can be composed using swaps.  The optimizer
needs to do the commuting optimization mentioned above,
but that can be deferred.

> I have not written any Unsafe support for floating-point types.  It's
> not clear to me that it is needed.  Perhaps the caller should convert
> floating-point types as necessary; what do you think?

Just bitwise load/store is fine IMO.  Clients can call floatToIntBits etc.

> There are several places in the JDK where we have special cases for
> alignment, endianness, and arrays and some could benefit from use of
> these new methods, but except for HeapByteBuffers I haven't changed
> anything.

It would be good to call them out; we can file followup bugs.

> I am aware that the code is uncommented.  I will fix that once we
> agree about what to do next.
> http://cr.openjdk.java.net/~aph/unaligned.hotspot.1/
> http://cr.openjdk.java.net/~aph/unaligned.jdk.2/

I like it!

I'm a little puzzled by the meaning of UseUnalignedAccesses.
From a portable point of view, it sounds like the JVM will be using special access operators.
But in fact, it is using the normal aligned memory access operators for unaligned accesses also.
(Remember, from a portability point of view the normal memory access operators work only on aligned addresses.)
I don't have a nice replacement name thought.

— John

More information about the hotspot-compiler-dev mailing list