javajvmjitjvm-hotspot

Confusion about HotSpot JVM JIT


For example,a loop with 10000 times in a method.When it runs 1000 times, the backedge_counter triggers the JIT compilation. And the interpreter continue executing. When it loops 4000 times, the JIT compilation completes.

My question is, how does the remainder 6000 times be executed, by interpreter, or execute native code?Or the native code is not executed until this method is invoked next time? And what happens when this method is invoked next time?


Solution

  • Assuming you are asking about HotSpot JVM, the answer is the remaining interations will be executed in compiled code.

    HotSpot JVM has a technique known as 'on-stack replacement' to switch from interpreter to compiled code while the method is running.

    http://openjdk.java.net/groups/hotspot/docs/HotSpotGlossary.html

    on-stack replacement
    Also known as 'OSR'. The process of converting an interpreted (or less optimized) stack frame into a compiled (or more optimized) stack frame. This happens when the interpreter discovers that a method is looping, requests the compiler to generate a special nmethod with an entry point somewhere in the loop (specifically, at a backward branch), and transfers control to that nmethod. A rough inverse to deoptimization.

    If you run JVM with -XX:+PrintCompilation flag, OSR compilations will be marked by % sign:

        274   27       3       java.lang.String::lastIndexOf (52 bytes)
        275   29       3       java.lang.String::startsWith (72 bytes)
        275   28       3       java.lang.String::startsWith (7 bytes)
        275   30       3       java.util.Arrays::copyOf (19 bytes)
        276   32       4       java.lang.AbstractStringBuilder::append (29 bytes)
        276   31  s    3       java.lang.StringBuffer::append (13 bytes)
        283   33 %     3       LoopTest::myLongLoop @ 13 (43 bytes)
                 ^                                    ^
                OSR                            bytecode index of OSR entry
    

    UPDATE

    Typically after OSR compilation a regular compilation is also queued, so that the next time the method is called, it will start running directly in compiled mode.

        187   32 %     3       LoopTest::myLongLoop @ 13 (43 bytes)
        187   33       3       LoopTest::myLongLoop (43 bytes)
    

    However, if a regular compilation is not complete by the time the method is called again, the method will start running in interpreter, and then will switch to OSR entry inside a loop.