Runtime intrinsic info

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Runtime intrinsic info

thurstonn
Hello,

Is there some way to verify that some particular method (say in Unsafe) is intrinsfied within a JVM at runtime?  Other than viewing the assembly code?
Something sort of like JOL does for class layout


Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Aaron Grunthal
-XX:+UnlockDiagnosticVMOptions -XX:+PrintIntrinsics

-XX:+PrintInlining also happens to provide that information


On 31.10.2015 21:40, thurstonn wrote:

> Hello,
>
> Is there some way to verify that some particular method (say in Unsafe) is
> intrinsfied within a JVM at runtime?  Other than viewing the assembly code?
> Something sort of like JOL does for class layout
>
>
> Thanks
>
>
>
> --
> View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850.html
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vladimir Ivanov
In reply to this post by thurstonn
The short answer is no.

Intrinsification is not a static property. In HotSpot some methods are
always intrinsifed and some are not (it depends on runtime conditions
and call site context). VM can decide on per-call site basis.

In 9 all "intrinsifiable" methods should be marked with
@HotSpotIntrinsicCandidate [1]. Otherwise, HotSpot complains.

In previous releases, -XX:+PrintInlining shows a message for every
intrinsified method.

Or, inspect HotSpot sources [2]. All intrinsics JVM knows about are
listed there.

Best regards,
Vladimir Ivanov

[1]
http://hg.openjdk.java.net/jdk9/jdk9/jdk/file/tip/src/java.base/share/classes/jdk/internal/HotSpotIntrinsicCandidate.java

[2]
http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/tip/src/share/vm/classfile/vmSymbols.hpp#l687


On 10/31/15 11:40 PM, thurstonn wrote:

> Hello,
>
> Is there some way to verify that some particular method (say in Unsafe) is
> intrinsfied within a JVM at runtime?  Other than viewing the assembly code?
> Something sort of like JOL does for class layout
>
>
> Thanks
>
>
>
> --
> View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850.html
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

thurstonn
So when I use +PrintInlining I see pretty much what I expect (e.g. the Unsafe CAS methods), but Unsafe#getAndSetObject isn't there, although it's listed in the jdk 8 vmSymbols.hpp file.

I'm using Oracle's JDK 1.8.0_45, so it really should be intrinsified, but maybe it's not among the methods that are always intrinsified?  Why would that be?
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vladimir Ivanov
Can you share the test case? I don't see any obvious reasons why
Unsafe.getAndSetObject isn't intrinsified in your case.

Best regards,
Vladimir Ivanov

On 11/1/15 11:57 PM, thurstonn wrote:

> So when I use +PrintInlining I see pretty much what I expect (e.g. the Unsafe
> CAS methods), but Unsafe#getAndSetObject isn't there, although it's listed
> in the jdk 8 vmSymbols.hpp file.
>
> I'm using Oracle's JDK 1.8.0_45, so it really should be intrinsified, but
> maybe it's not among the methods that are always intrinsified?  Why would
> that be?
>
>
>
> --
> View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12853.html
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

thurstonn
So after a variety of trial and error, the output shows that AtomicReference#getAndSet is being inlined and
sun.misc.Unsafe::getAndSetObject is marked intrinsic.

It must have been a case where I was initially using a local AtomicReference that the JVM identified as being only accessible from a single thread?

Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vladimir Ivanov
I don't believe HotSpot C2 can eliminate Unsafe::getAndSetObject if it
is accessible from a single thread.

If Unsafe::getAndSetObject isn't present in compilation output, it means
JIT didn't compile the call site at all. Effectively dead code maybe?

Otherwise, if intrinsic substitution failed, the call should be reported
as a native call. But Unsafe::getAndSetObject should be present in
compilation log irrespectively of whether the method was intrinsified or
not.

So, I'd like to see the test case anyway to understand what is going on.

Best regards,
Vladimir Ivanov

On 11/3/15 2:05 AM, thurstonn wrote:

> So after a variety of trial and error, the output shows that
> AtomicReference#getAndSet is being inlined and
> sun.misc.Unsafe::getAndSetObject is marked intrinsic.
>
> It must have been a case where I was initially using a local AtomicReference
> that the JVM identified as being only accessible from a single thread?
>
>
>
>
>
> --
> View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12855.html
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Nathan Reynolds-2
HotSpot has logic to detect if running on a 1 core/processor machine.  The default behavior was to change each atomic instruction into 1 regular instruction.  Since there is only 1 processor, the 1 regular instruction's impact is atomic since a context switch can't split an instruction's impact.  The default behavior was changed to keep the atomic instructions and with a command line switch to turn it on.  Thus, one could dynamically add processors and not cause problems in the compiled code.

This is a long shot... could it be that HotSpot eliminated the Unsafe::getAndSetObject because HotSpot is converting it into a regular instruction?  It seems the compilation log would still say something about it.
-Nathan
On 11/3/2015 4:25 AM, Vladimir Ivanov wrote:
I don't believe HotSpot C2 can eliminate Unsafe::getAndSetObject if it is accessible from a single thread.

If Unsafe::getAndSetObject isn't present in compilation output, it means JIT didn't compile the call site at all. Effectively dead code maybe?

Otherwise, if intrinsic substitution failed, the call should be reported as a native call. But Unsafe::getAndSetObject should be present in compilation log irrespectively of whether the method was intrinsified or not.

So, I'd like to see the test case anyway to understand what is going on.

Best regards,
Vladimir Ivanov

On 11/3/15 2:05 AM, thurstonn wrote:
So after a variety of trial and error, the output shows that
AtomicReference#getAndSet is being inlined and
sun.misc.Unsafe::getAndSetObject is marked intrinsic.

It must have been a case where I was initially using a local AtomicReference
that the JVM identified as being only accessible from a single thread?





--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12855.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vitaly Davidovich
I just tried using a local AtomicReference, and 8u51 does not EA it out and shows intrinsic info.

On Tue, Nov 3, 2015 at 8:44 AM, Nathan Reynolds <[hidden email]> wrote:
HotSpot has logic to detect if running on a 1 core/processor machine.  The default behavior was to change each atomic instruction into 1 regular instruction.  Since there is only 1 processor, the 1 regular instruction's impact is atomic since a context switch can't split an instruction's impact.  The default behavior was changed to keep the atomic instructions and with a command line switch to turn it on.  Thus, one could dynamically add processors and not cause problems in the compiled code.

This is a long shot... could it be that HotSpot eliminated the Unsafe::getAndSetObject because HotSpot is converting it into a regular instruction?  It seems the compilation log would still say something about it.
-Nathan
On 11/3/2015 4:25 AM, Vladimir Ivanov wrote:
I don't believe HotSpot C2 can eliminate Unsafe::getAndSetObject if it is accessible from a single thread.

If Unsafe::getAndSetObject isn't present in compilation output, it means JIT didn't compile the call site at all. Effectively dead code maybe?

Otherwise, if intrinsic substitution failed, the call should be reported as a native call. But Unsafe::getAndSetObject should be present in compilation log irrespectively of whether the method was intrinsified or not.

So, I'd like to see the test case anyway to understand what is going on.

Best regards,
Vladimir Ivanov

On 11/3/15 2:05 AM, thurstonn wrote:
So after a variety of trial and error, the output shows that
AtomicReference#getAndSet is being inlined and
sun.misc.Unsafe::getAndSetObject is marked intrinsic.

It must have been a case where I was initially using a local AtomicReference
that the JVM identified as being only accessible from a single thread?





--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12855.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

thurstonn
In reply to this post by Vladimir Ivanov
So, it's one of those engineering ironies that at first, I couldn't get the JVM to inline and intrinsify #getAndSet, and now I can't get it to *not* intrinsify.

IIRC, the original code was something like:
for (int i = 0; i < 10_000; i++)
 {
            //assertNotNull(this.ref.getAndSet(new Object()));
       System.err.println(new AtomicReference().getAndSet(new Object()));
 }
but when I run that now, I see:
992  292       3       java.util.concurrent.atomic.AtomicReference::getAndSet (12 bytes)
          @ 8   sun.misc.Unsafe::getAndSetObject (24 bytes)   intrinsic

in the output.
You can shorten the loop (e.g. 1_000) and you won't see any intrinsic output, but that's because the JIT inline threshold isn't reached.

I swear that I had a 10K iteration that produced no compilation intrinsic output, but I can't reproduce it now
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Alex Otenko
In reply to this post by Nathan Reynolds-2
It used to have such logic. I think it has been removed. There were issues with the machines where the CPU count appeared 1, but turned out more than 1 later (tinkering with numactl during JVM lifetime). No matter how common such a case is, the saving these days probably wasn’t worth the effort.

Alex


On 3 Nov 2015, at 13:44, Nathan Reynolds <[hidden email]> wrote:

HotSpot has logic to detect if running on a 1 core/processor machine.  The default behavior was to change each atomic instruction into 1 regular instruction.  Since there is only 1 processor, the 1 regular instruction's impact is atomic since a context switch can't split an instruction's impact.  The default behavior was changed to keep the atomic instructions and with a command line switch to turn it on.  Thus, one could dynamically add processors and not cause problems in the compiled code.

This is a long shot... could it be that HotSpot eliminated the Unsafe::getAndSetObject because HotSpot is converting it into a regular instruction?  It seems the compilation log would still say something about it.
-Nathan
On 11/3/2015 4:25 AM, Vladimir Ivanov wrote:
I don't believe HotSpot C2 can eliminate Unsafe::getAndSetObject if it is accessible from a single thread.

If Unsafe::getAndSetObject isn't present in compilation output, it means JIT didn't compile the call site at all. Effectively dead code maybe?

Otherwise, if intrinsic substitution failed, the call should be reported as a native call. But Unsafe::getAndSetObject should be present in compilation log irrespectively of whether the method was intrinsified or not.

So, I'd like to see the test case anyway to understand what is going on.

Best regards,
Vladimir Ivanov

On 11/3/15 2:05 AM, thurstonn wrote:
So after a variety of trial and error, the output shows that
AtomicReference#getAndSet is being inlined and
sun.misc.Unsafe::getAndSetObject is marked intrinsic.

It must have been a case where I was initially using a local AtomicReference
that the JVM identified as being only accessible from a single thread?





--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12855.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vitaly Davidovich
In reply to this post by thurstonn
If you're using exactly 10k iterations and not tweaking the CompileThreshold, then it's probably a good idea to specify -Xbatch to make the java thread wait for JIT compilation to finish.  Perhaps your previous run finished before compilation completed, and it wasn't printed? Just a thought.

On Tue, Nov 3, 2015 at 9:36 AM, thurstonn <[hidden email]> wrote:
So, it's one of those engineering ironies that at first, I couldn't get the
JVM to inline and intrinsify #getAndSet, and now I can't get it to *not*
intrinsify.

IIRC, the original code was something like:
for (int i = 0; i < 10_000; i++)
 {
            //assertNotNull(this.ref.getAndSet(new Object()));
       System.err.println(new AtomicReference().getAndSet(new Object()));
 }
but when I run that now, I see:
992  292       3
java.util.concurrent.atomic.AtomicReference::getAndSet (12 bytes)
          @ 8   sun.misc.Unsafe::getAndSetObject (24 bytes)   intrinsic

in the output.
You can shorten the loop (e.g. 1_000) and you won't see any intrinsic
output, but that's because the JIT inline threshold isn't reached.

I swear that I had a 10K iteration that produced no compilation intrinsic
output, but I can't reproduce it now



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12859.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

thurstonn
It does bring up an interesting question, viz. why is Unsafe#getAndSetObject being treated differently than say Unsafe::compareAndSwapObject ?

The former's intrinsification appears to happen only upon JIT compilation threshold triggering (10K), while the latter doesn't (or at least has a much smaller threshold).
Why would that be?

A little background: I ran my code as a JUnit test, and as described in an earlier post, I could see the Unsafe::compareAndSwapObject (intrinsic) in the output (the JUnit test harness must either directly/indirectly invoke the CAS).

Not sure I see the reasoning for the differential treatment
Reply | Threaded
Open this post in threaded view
|

Re: Runtime intrinsic info

Vitaly Davidovich
The former's intrinsification appears to happen only upon JIT compilation
threshold triggering (10K), while the latter doesn't (or at least has a much
smaller threshold).
Why would that be?

What do you mean exactly? Can you show some compilation/inlining output that you're using to make the above suggestion? When your callsite using AtomicReference reaches compilation threshold, it'll typically inline the AR method(s) and then replace the java code with intrinsic implementation (this is all part of the compilation+optimization phase).  The AR methods can also be inlined into other callsites, which may reach compilation threshold earlier. 

On Tue, Nov 3, 2015 at 10:56 AM, thurstonn <[hidden email]> wrote:
It does bring up an interesting question, viz. why is Unsafe#getAndSetObject
being treated differently than say Unsafe::compareAndSwapObject ?

The former's intrinsification appears to happen only upon JIT compilation
threshold triggering (10K), while the latter doesn't (or at least has a much
smaller threshold).
Why would that be?

A little background: I ran my code as a JUnit test, and as described in an
earlier post, I could see the Unsafe::compareAndSwapObject (intrinsic) in
the output (the JUnit test harness must either directly/indirectly invoke
the CAS).

Not sure I see the reasoning for the differential treatment



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/Runtime-intrinsic-info-tp12850p12862.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest