Acquire/Release vs Volatile in VarHandle

Gianluca Stivan me at yawnt.com
Wed Jul 19 13:41:04 UTC 2017


Hi,

thanks Andrew, Aleksey! (I will make sure I post to hotspot-dev next time).

Actually the trick with JMH has been proving very helpful. I had already
compiled hsdis-arm.so because of unrelated tests, so I was easy to just
hook that up.
I tried running two tests, one using 3 setVolatiles calls, the other using
3 setOpaque/setRelease and JMH identified the three following hot regions:

c1, java.lang.invoke.VarHandleInts$FieldStaticReadWrite::setRelease
c1, java.lang.invoke.VarHandleInts$FieldStaticReadWrite::setVolatile
c1, java.lang.invoke.VarHandleInts$FieldStaticReadWrite::setOpaque

The assembly generated is identical in all three cases, so from what I can
see, it does seem that indeed there is no difference.
Result is similar with fences: fullFence and releaseFence both compile to
`dmb sy`.

The one thing that I was wondering tho, is that all those methods are from
C1. I read that increasing the iterations is more likely to trigger C2, but
that didn't happen.
Would that change anything, in your opinion, or would C2 optimizations be
unrelated to this scenario?

Thank you very much again!

Gianluca


2017-07-18 18:54 GMT+02:00 Aleksey Shipilev <shade at redhat.com>:

> On 07/18/2017 10:30 AM, Gianluca Stivan wrote:
> > I've been experimenting with the new VarHandle APIs and especially the
> > Acquire/Release and Opaque modes. To my understanding they should map
> > pretty much 1-1 to the memory_order_{acquire,release} and
> > memory_order_relaxed on C++11.
>
> Yup, see more details here:
>   http://gee.cs.oswego.edu/dl/html/j9mm.html
>
> > // Unsafe
> > @HotSpotIntrinsicCandidate
> > public final Object getObjectAcquire(Object o, long offset) {
> >   return getObjectVolatile(o, offset);
> > }
>
> This is the fallback version. The actual method body would be generated by
> an
> optimizing compiler, if available and enabled (see
> @HotSpotIntrinsicCandidate).
>
> It would be more revealing to see the generated code with, e.g. JMH -prof
> perfasm, as in:
>  http://hg.openjdk.java.net/code-tools/jmh/file/
> a128fd4a5901/jmh-samples/src/main/java/org/openjdk/jmh/
> samples/JMHSample_35_Profilers.java#l321
>
> ...that would require hsdis compiled for ARMv7, though.
>
> > I then thought, if I can't lower my constraints using the VarHandle APIs,
> > maybe I could use fences. But again the results are similar. After some
> > more digging, it appears that release/acquire fences compile to a full
> > fence (at least on linux_arm).
> >
> > // orderAccess_linux_arm.inline.hpp
> > inline void OrderAccess::acquire()    { dmb_ld(); }
> > inline void OrderAccess::release()    { dmb_sy(); }
> > inline void OrderAccess::fence()      { dmb_sy(); }
>
> These are for use from VM code, and they have nothing to do with Java
> intrinsics
> that are compiled differently. I think Java fences go through Unsafe -> C2
> intrinsics -> arm.ad -> MacroAssembler here:
>
> http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/
> 791a8c45a354/src/cpu/arm/vm/macroAssembler_arm.cpp#l1761
>
> ...which seems to corroborate that ARM fences are compiled to dmb_sy,
> except for
> storestore that compiles to dmb_st. Not on AArch64 though, see another
> definition above.
>
> Thanks,
> -Aleksey.
>
>
>


More information about the jdk9-dev mailing list