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.