Reference.reachabilityFence

Peter Levart peter.levart at gmail.com
Mon Nov 23 23:09:29 UTC 2015


Hi,

On 11/23/2015 05:50 PM, Vitaly Davidovich wrote:
> Hi Paul,
>
> Glad you guys are addressing this.
>
> It looks like C1 and C2 will actually call this method.  Is the longer term
> plan to teach the compilers that this method does not need to be called but
> rather expand the live range of the reference?

It seems that (at least sometimes) compiler(s) are able to do just that.

With the following test:

http://cr.openjdk.java.net/~plevart/misc/ReachabilityFence/ReachabilityFence2.java

Even a simple empty static method "inlineableNoOp(Object)" acts as a 
reachabilityFence.

When invoked with:

-Dpremature=true
-XX:+IgnoreUnrecognizedVMOptions
-showversion
-server
-XX:-TieredCompilation
-Xbatch
-Xcomp
-XX:+PrintCompilation
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining


...we can see that inlineableNoOp() is in fact inlined, but the test 
still passes (if the call to inlineableNoOp() is removed it fails!)


    2771 1161    b        ReachabilityFence2::fenced (38 bytes)
                             @ 0   java.lang.System::nanoTime (0 
bytes)   (intrinsic)
                             @ 9   ReachabilityFence2::fencedTry (30 
bytes)   inline (hot)
                               @ 4 
ReachabilityFence2$MyFinalizeable::<init> (16 bytes)   inline (hot)
                                 @ 1   java.lang.Object::<init> (1 
bytes)   inline (hot)
                                 @ 9 
java.util.concurrent.atomic.AtomicBoolean::<init> (5 bytes) inline (hot)
                                   @ 1 java.lang.Object::<init> (1 
bytes)   inline (hot)
                !              @ 14   ReachabilityFence2::doGc (22 
bytes)   inline (hot)
                               @ 18 
java.util.concurrent.atomic.AtomicBoolean::get (13 bytes)   inline (hot)
                               @ 24 ReachabilityFence2::inlineableNoOp 
(1 bytes)   inline (hot)
                             @ 25   java.lang.System::nanoTime (0 
bytes)   (intrinsic)
                             @ 9   ReachabilityFence2::fencedTry (30 
bytes)   inline (hot)
                               @ 4 
ReachabilityFence2$MyFinalizeable::<init> (16 bytes)   inline (hot)
                                 @ 1   java.lang.Object::<init> (1 
bytes)   inline (hot)
                                 @ 9 
java.util.concurrent.atomic.AtomicBoolean::<init> (5 bytes) inline (hot)
                                   @ 1 java.lang.Object::<init> (1 
bytes)   inline (hot)
                !              @ 14   ReachabilityFence2::doGc (22 
bytes)   inline (hot)
                                 @ 8   java.lang.System::gc (7 bytes)   
inline (hot)
                                   @ 0 java.lang.Runtime::getRuntime (4 
bytes)   inline (hot)
                                   @ 3   java.lang.Runtime::gc (0 
bytes)   native method
                                 @ 14   java.lang.Thread::sleep (0 
bytes)   native method
                               @ 18 
java.util.concurrent.atomic.AtomicBoolean::get (13 bytes)   inline (hot)
                               @ 24 ReachabilityFence2::inlineableNoOp 
(1 bytes)   inline (hot)


When invoked with:

-Dpremature=true
-XX:+IgnoreUnrecognizedVMOptions
-showversion
-server
-XX:TieredStopAtLevel=1
-Xbatch
-Xcomp
-XX:+PrintCompilation
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining


The test passes and prints:

     904  837    b  1       ReachabilityFence2::fenced (38 bytes)
                               @ 0   java.lang.System::nanoTime (0 
bytes)   intrinsic
                               @ 9   ReachabilityFence2::fencedTry (30 
bytes)
                                 @ 4 
ReachabilityFence2$MyFinalizeable::<init> (16 bytes)
                                   @ 1 java.lang.Object::<init> (1 bytes)
                                   @ 9 
java.util.concurrent.atomic.AtomicBoolean::<init> (5 bytes)
                                     @ 1 java.lang.Object::<init> (1 bytes)
                !                @ 14   ReachabilityFence2::doGc (22 bytes)
                                   @ 8   java.lang.System::gc (7 bytes)
                                     @ 0 java.lang.Runtime::getRuntime 
(4 bytes)
                                     @ 3   java.lang.Runtime::gc (0 
bytes)   native method
                                   @ 14   java.lang.Thread::sleep (0 
bytes)   native method
                                 @ 18 
java.util.concurrent.atomic.AtomicBoolean::get (13 bytes)
                                 @ 24 ReachabilityFence2::inlineableNoOp 
(1 bytes)
                               @ 25   java.lang.System::nanoTime (0 
bytes)   intrinsic


This seems to indicate that for establishing a reachability even 
inlineable no-op (empty) method with single argument is enough.

It might not be enough in every situation, but what this means is that 
it will be very difficult to write a positive test for 
Reference.reachabilityFence(Object) when we can't write a negative test 
with a simple inlineable static no-op method. I haven't been able to 
come-up with a form of code that passes the negative test (nonFenced) 
and call the inlineableNoOp in the process.


Regards, Peter


> Thanks
>
> On Mon, Nov 23, 2015 at 11:38 AM, Paul Sandoz <paul.sandoz at oracle.com>
> wrote:
>
>> Hi,
>>
>> Please review the addition of Reference.reachabilityFence contributed by
>> Aleksey, Doug and myself:
>>
>>
>> http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8133348-reachability-fence-jdk/webrev/
>>
>> http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8133348-reachability-fence-hotspot/webrev/
>>
>> The implementation approach marks the method Reference.reachabilityFence
>> as not inline-able, thereby “keeping alive” an object passed to the method
>> until at least after the method call.
>>
>> The testing approach i have taken is to verify that the method does not
>> get inlined either in C1 or C2. The test approach seems fragile (as fragile
>> as the accessor-based test i code-cargo-culted from) but passes ok through
>> JPRT.
>>
>> I could not find a suitable mechanism in WhiteBox. Is there a more
>> reliable mechanism to determine what methods are inlined into a compiled
>> method?
>>
>> There is another testing approach in the VarHandles sandbox:
>>
>>    http://hg.openjdk.java.net/jdk9/sandbox/jdk/rev/433114b32d2d#l2.2
>>
>> But i am not confident that the test can be run within a reasonable time
>> and reliably on all platforms and VM modes.
>>
>> Paul.
>>
>>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20151124/17fef2fc/attachment.html>


More information about the hotspot-compiler-dev mailing list