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 mechanical-sympathy+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.