Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • The compiler may stub out an untaken branch and deoptimize if it is ever taken.
  • Similarly for low-level safety checks that have historically never failed.
  • If a call site or cast encounters an unexpected type, the compiler deoptimizes.
  • If a class is loaded that invalidates an earlier class hierarchy analysis, any affected method activations, in any thread, are forced to a safepoint and deoptimized.
  • Such indirect deoptimization is mediated by the dependency system. If the compiler makes an unchecked assumption, it must register a checkable dependency. (E.g., that class Foo has no subclasses, or method Foo.bar is has no overrides.)

Methods

  • Methods are often inlined. This increases the compiler's "horizon" of optimization.
  • Static, private, final, and/or "special" invocations are easy to inline.
  • Virtual (and interface) invocations are often demoted to "special" invocations, if the class hierarchy permits it. A dependency is registered in case further class loading spoils things.
  • Virtual (and interface) invocations with a lopsided type profile are compiled with an optimistic check in favor of the historically common type (or two types).
  • Depending on the profile, a failure of the optimistic check will either deoptimize or run through a (slow) vtable/itable call.
  • On the fast path of an optimistically typed call, inlining is common. The best case is a de facto monomorphic call which is inlined. Such calls, if back-to-back, will perform the receiver type check only once.
  • In the absence of strong profiling information, a virtual (or interface) call site will be compiled in an agnostic state, waiting for the first execution to provide a provisional monomorphic receiver. (This is called an "inline cache".)
  • An inline cache will flip to a monomorphic state at the first call, and stay in that state as long as the exact receiver type (not a subtype) is repeated every time.
  • An inline cache will flip to a "megamorphic" state if a second receiver type is encountered.
  • Megamorphic calls use assembly-coded vtable and itable stubs, patched in by the JVM. The compiler does not need to manage them.

...