OpenJDK - C1 Intrinsify Example
C1: Intrinsify Class.getModifier method is relatively simple and
straightforward example to intrinsify getModifier
method. However, as I know very little about JIT, the
patch is beyond my comprehension. Therefore, I took a blackbox
approach to see its effect first before trying to understand how it is implemented.
§Simple Java Program
Here’s a trivial java program calling getModifiers
.
1 | // in hello.java |
§Running
Normally, one can just run java <filename>
, but we wanna see some additional info for our little experiment, so we use
a simple shell script as the runner:
1 | !/usr/bin/zsh |
Since we are only interested in how hello.f
is compiled , we disable inline (DontInline
) for it, and exclude
compilation (CompileOnly
) for other methods. Additionally, we disable C2 (TieredStopAtLevel=3
) to reduce noise in
the output. Finally, we use -Xcomp
to force compilation (effectively disabling the interpreter) before executing a
method; otherwise, our single invocation of f
in main
will not trigger compilation.
§Results
The interesting part is around getModifiers
:
§before.txt
1 | 0x00007f48fdf1520f: call 0x00007f48fd82da80 ; ImmutableOopMap {} |
§after.txt
There’s no reference to getModifier
in the assembly; instead, it’s just a plain mov
. The 0x411
literal seems a bit
magical; if we print the final result of y
, we will see 0x411
as well. IOW, int.class.getModifier()
is 0x411
,
and C1 has completely replaced the original method call with a literal.
1 | 0x00007f2e1104861a: mov DWORD PTR [rsi+0x70],0x411 ;*putstatic y {reexecute=0 rethrow=0 return_oop=0} |
§Summary
After seeing the end effect of this patch, we are hopefully getting a better mental picture on what this patch does. With that info in mind, we can re-read this patch without feeling overwhelmed.