I understand how on-stack replacement (OSR) generally works, but what I don't understand is whether an OSR compiled method is ever useful once the method leaves the initial invocation that triggered the compilation - can the JITed code be used on a subsequent iteration?
It seems like it could, once the interpreter proceeds to the same bytecode index that the old OSR kicked off at it could again enter the OSR-compiled method.
I'm asking mostly because I'm seeing a case where Hotspot immediately OSR compiles my method twice (for different BCIs), but doesn't even do a normal C2 non-OSR compile until it has been running for a couple of minutes (despite a million calls or more to the method). So I'm wondering if it is using the OSR C2 method in the meantime (there is also a non-OSR C1 method)?
Yes, they can be reused. But only at the same bytecode index they were generated for, and only in response to back branch event of the compilation policy.
HotSpot
InstanceKlass
structure (an internal representation of Java class) keeps a list of OSR methods for the class. Whenever a compilation is requested, CompileBroker looks for an existing NMethod in this list.I can't tell much about your particular case without a closer look, but from the given description I suspect that your application calls C1-compiled version. Method's entry point is never set to OSR-compiled NMethod.