java PrintCompilation output: what's the meaning of "made not entrant" and "made zombie"

Joe Kearney picture Joe Kearney · May 28, 2010 · Viewed 8.5k times · Source

When running a Java 1.6 (1.6.0_03-b05) app I've added the -XX:+PrintCompilation flag. On the output for some methods, in particular some of those that I know are getting called a lot, I see the text made not entrant and made zombie.

What do these mean? Best guess is that it's a decompilation step before recompiling either that method or a dependency with greater optimisation. Is that true? Why "zombie" and "entrant"?

Example, with quite a bit of time between some of these lines:

[... near the beginning]
42       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... much later]
42    made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
---   n   sun.misc.Unsafe::compareAndSwapObject
170       jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
  4%      jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes)
171       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... even later]
42    made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
170   made zombie  jsr166y.LinkedTransferQueue::xfer (294 bytes)
171   made not entrant  jsr166y.LinkedTransferQueue::xfer (294 bytes)
172       jsr166y.LinkedTransferQueue::xfer (294 bytes)

[... no further logs]

Answer

JodaStephen picture JodaStephen · Aug 21, 2011

I've pulled together some info on this on my blog. A Cliff Click comment I found says:

Zombie methods are methods whose code has been made invalid by class loading. Generally the server compiler makes aggressive inlining decisions of non-final methods. As long as the inlined method is never overridden the code is correct. When a subclass is loaded and the method overridden, the compiled code is broken for all future calls to it. The code gets declared "not entrant" (no future callers to the broken code), but sometimes existing callers can keep using the code. In the case of inlining, that's not good enough; existing callers' stack frames are "deoptimized" when they return to the code from nested calls (or just if they are running in the code). When no more stack frames hold PC's into the broken code it's declared a "zombie" - ready for removal once the GC gets around to it.