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.