EVALUATION
Compiled method is larger in newer JVM, because of increased size of
uncommon (cold) paths. The hot code is about the same size, but our
heuristic does not measure hot code size. It should; this is an old
problem. See comparative nmethod dumps below.
A reasonable solution would be to record, on the nmethod, an offset
which estimates the end of the hot code. (The compiler attempts to
lay all cold code out after all hot code.) This offset can be
estimated (for example) in Compile::Output, near the comment which
says "Insert epilogs before every return", by noting the offset of the
latest return (usually the only return).
Note that AMD64 does not manifest this bug because the invoke call is
*never* inlined, because InlineSmallCode is too small for a 64-bit
machine. This also should be fixed.
In this case, the extra cold code comes from a path taken just once.
The older compiler treats this path as never-taken, because the MDO
has no record of the path. But the newer compiler treats the path as
seldom-taken (which is more accurate), and therefore emits cold code
for it, calling ensureMemberAccess from Method.invoke (at bci 111).
This extra cold code bloats the compiled method and fools the inlining
heuristic.
--- Comparative nmethod dumps ---
Bad version of code:
Compiled 4 nmethod java.lang.reflect.Method::invoke (167 bytes)
total in heap [0xfa2ce588,0xfa2cf050] = 2760
relocation [0xfa2ce634,0xfa2ce698] = 100
main code [0xfa2ce6a0,0xfa2ceba0] = 1280 (** greater than InlineSmallCode)
main code, hot part = 531 (** up to RET opcode only)
exception code [0xfa2ceba0,0xfa2cebc0] = 32
stub code [0xfa2cebc0,0xfa2cebe8] = 40
scopes data [0xfa2cebe8,0xfa2cedfc] = 532
scopes pcs [0xfa2cedfc,0xfa2cefbc] = 448
dependencies [0xfa2cefbc,0xfa2cefc0] = 4
handler table [0xfa2cefc0,0xfa2cf020] = 96
nul chk table [0xfa2cf020,0xfa2cf044] = 36
oops [0xfa2cf044,0xfa2cf050] = 12
Good version of code:
Compiled 4 nmethod java.lang.reflect.Method::invoke (167 bytes)
total in heap [0xfa4cec88,0xfa4cf510] = 2184
relocation [0xfa4ced34,0xfa4ced8c] = 88
main code [0xfa4ceda0,0xfa4cf100] = 864 (** less than InlineSmallCode)
main code, hot part = 519 (** up to RET opcode only)
exception code [0xfa4cf100,0xfa4cf120] = 32
stub code [0xfa4cf120,0xfa4cf13e] = 30
constants [0xfa4cf13e,0xfa4cf140] = 2
scopes data [0xfa4cf140,0xfa4cf30c] = 460
scopes pcs [0xfa4cf30c,0xfa4cf49c] = 400
dependencies [0xfa4cf49c,0xfa4cf4a0] = 4
handler table [0xfa4cf4a0,0xfa4cf4e8] = 72
nul chk table [0xfa4cf4e8,0xfa4cf504] = 28
oops [0xfa4cf504,0xfa4cf510] = 12
|