Gil really thank you for the super detailed answer!
I'm digesting it and I've found an interesting talk with some of these
concepts referenced/mentioned: https://youtu.be/oH4_unx8eJQ?t=4503
Douglas Hawkins:"...the compilation is shared by all threads...all threads.
One thread behave badly, all threads suffer."
After your explanation I would say: "..almost all threads..."
But considering that is about deopt it doesn't make sense such precise!
My initial fairytale idea of what a JVM should able to optimize was
"probably" too imaginative eg 2 threads T1,T2 calling the same static
method:
static void foo(..){
if(cond){
uncommonCase();
}
}
T1 with cond = true while T2 with cond = false.
My "fairytale JVM" were able to optimize each specific call of foo() for
the 2 threads with specific compiled (inlined if small enough) versions
that benefit each one of the real code paths executed (ie uncommonCase()
inlined/compiled just for T1).
Obviously the fairytale optimizations weren't only specific per-thread but
per call-site too :P
After your answer I'm starting to believe that Santa Claus doesn't exists
and it's not his fault :)
Thanks,
Franz
Il giorno sabato 27 gennaio 2018 18:45:28 UTC+1, Gil Tene ha scritto:
>
> Some partial answers inline below, which can probably be summarized with
> "it's complicated...".
>
> On Friday, January 26, 2018 at 8:33:53 AM UTC-8, Francesco Nigro wrote:
>
> HI guys,
>>
>> in the last period I'm having some fun playing with JItWatch (many thanks
>> to Chris Newland!!!) and trying to understand a lil' bit more about
>> specific JVM optimizations, but suddenly I've found out that I was missing
>> one of the most basic definition: call site.
>>
>> I've several questions around that:
>>
>> 1. There is a formal definition of call site from the point of view
>> of the JIT?
>>
>> I don't know about "formal". But a call site is generally any location
> in the bytecode of one method that explicitly causes a call to another
> method. These include:
>
> classic bytecodes used for invocation:
> - Virtual method invocation (invokevirtual and invokeinterface, both of
> which calling a non-static method on an instance), which in Java tends to
> dynamically be the most common form.
> - Static method invocations (invokestatic)
> - Constructor/initializer invocation (invokespecial)
> - Some other cool stuff (private instance method invocation with
> invokespecial, native calls, etc.)
>
> In addition, you have these "more interesting" things that can be viewed
> (and treated by the JIT) as call sites:
> - MethodHandle.invoke*()
> - reflection based invocation (Method.invoke(), Constructor.newInstance())
> - invokedynamic (can full of Pandora worms goes here...)
>
>
>> 1. I know that there are optimizations specific per call site, but
>> there is a list of them somewhere (that is not the OpenJDK source code)?
>>
>> The sort of optimizations that might happen at a call site can evolve
> over time, and JVMs and JIT can keep adding newer optimizations: Some of
> the current common call site optimizations include:
>
> - simple inlining: the target method is known (e.g. it is a static
> method, a constructor, or a
> we-know-there-is-only-one-implementor-of-this-instance-method-for-this-type-and-all-of-its-subtypes),
>
> and can be unconditionally inlined at the call site.
> - guarded inlining: the target method is assumed to be a specific method
> (which we go ahead and inline), but a check (e.g. the exact type of this
> animal is actually a dog) is required ahead of the inlined code because we
> can't prove the assumption is true.
> - bi-morphic and tri-morphic variants of guarded inlining exist (where two
> or three different targets are inlined).
> - Inline cache: A virtual invocation dispatch (which would need to follow
> the instance's class to locate a target method) is replaced with a guarded
> static invocation to a specific target on the assumption a specific
> ("monomorphic") callee type. "bi-morphic" and "tri-morphic" variants of
> inline cache exist (where one of two or three static callees are called
> depending on a type check, rather than performing a full virtual dispatch)
> ...
>
> But there are bigger and more subtle things that can be optimized at and
> around a call site, which may not be directly evident from the calling code
> itself. Even when a call site "stays", things like this can happen:
>
> - Analysis of all possible callees shows that no writes to some locations
> are possible and that no order-enforcing operations will occur, allowing
> the elimination of re-reading of those locations after the call. [this can
> e.g. let us hoist reads out of loops containing calls].
> - Analysis of all possible callees shows that no reads of some locations
> are possible and that no order-enforcing operations will occur, allowing
> the delay/elimination of writes to those locations [this can e.g. allow us
> to sink writes such that occur once after a loop with calls in it].
> - Analysis of all possible callees shows that an object passed as an
> argument does not escape to the heap, allowing certain optimizations (e.g.
> eliminating locks on the object if it was allocated in the caller and never
> escaped since we now know it is thread-local)
> - ... (many more to come)
>
>
>> 1.
>> 2. I know that compiled code from the JVM is available in a Code
>> Cache to allow different call-sites to use it: that means that the same
>> compiled method is used in all those call-sites (provided that's the best
>> version of it)?
>>
>>
> Not necessarily.
>
>
> - The same method may exist in the code cache in multiple places:
> - Each tier may retain compiles of the same method.
> - Methods compiled for OSR-entry (e.g. transition from a lower tier
> version of the same method in the middle of a long-running loop) are
> typically a separate code cache entry that ones compiled for entry via
> normal invocation.
> - Each location where a method is inlined is technically a separate copy
> of that method in the cache.
> - ...
>
> - When an actual virtual invocation is made, that invocation will normally
> go to the currently installed version of the method in the code cache (if
> one exists). However, because the JVM works very hard to avoid actual
> virtual invocations (and tend to succeed in doing this 90%+ of the time)
> some invocation sites may call other versions of the same method.
>
> - Some optimizations and/or profiling techniques may end up creating two
> or more different and specialized compiled versions of the same
> method, choosing which one to call depending on things that are known to or
> decided by the caller.
>
>
>>
>> 1.
>>
>> I hope to not have asked too naive questions :)
>>
>> thanks
>> Franz
>>
>>
--
You received this message because you are subscribed to the Google Groups
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.