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.san...@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.