Offline Compilation¶
Maxine VM supports offline compilation of Java methods. Offline compilation essentially invokes Maxine VM’s compilers through the host VM. This process allows users to inspect the whole process of code generation without the need to build a Maxine VM image. Some of the use cases of offline compilation are listed below:
- Debugging when implementing the compiler back-ends for a new ISA.
- Debugging when implementing new JIT optimizations.
- Inspecting how code generation works for educational purposes.
Warning
The output is not guaranteed to be the same as the output for a compilation performed at run-time. The code produced by a compiler is sensitive to the compilation context such as what classes have been resolved etc.
To compile offline the main
method of Main
class issue the following command:
$ mx olc -cp ./ -c=C1X ^Main:main^
Initializing Java prototype... done
Main.main(String[])
.
1 passed
Note
On Mac OS you will need to install binutils (brew install binutils
) and change your PATH
(export PATH="/usr/local/opt/binutils/bin:$PATH"
).
mx olc
invokes the offline compilation-cp ./
adds the current path to the classpath. This is necessary for the online compilation to find the class we want to compile. Depending on your project structure you might need to pass a different directory than the current one.-c=C1X
defines the Maxine compiler to be used. This option supportsT1X
andC1X
at the moment.
Note
Using T1X
will also invoke C1X
to generate the machine code for the T1X templates.
The method however will be compiled using T1X
^Main:main^
defines the methods to be compiled. This is essentially a pattern.
The above command will generate a folder olc
with two files in it:
Main.main-C1X-amd64.bin
contains the raw machine code generated by the compiler.Main.main-C1X-amd64.S
contains the assembly code obtained by disassemblingMain.main-C1X-amd64.bin
.
C1visualizer¶
To better understand C1X code generation and how the code gets translated from Java byte-code to machine code we use the c1visualizer.
C1visualizer expects a cfg file as input.
To generate this file we can run mx olc
with the -C1X:+PrintCFGToFile
.
Note
This will generate a single compilations*.cfg
file for all the methods matching the pattern.
More options¶
Another option is to generate assembly code annotated with LIR instructions:
$ mx olc -cp ./ -c=C1X -C1X:+PrintLIRWithAssembly ^Main:main^
Initializing Java prototype... done
Main.main(String[])
B0 [0, 0] . B1 0 Label ?
2 XIR: prologue()
0x0: e8 00 00 00 00 callq 0x5
0x5: 90 nop
0x6: 90 nop
0x7: 90 nop
0x8: 48 83 ec 28 sub $0x28,%rsp
0xc: 48 89 84 24 28 e0 ff mov %rax,-0x1fd8(%rsp)
0x13: ff
B1 (SV)[0, 3] . B4 dom B0 pred: B0 8 Label ?
10 move rsi:i = const[1|0x1]:i
0x14: be 01 00 00 00 mov $0x1,%esi
12 move rax:i = const[1|0x1]:i
0x19: b8 01 00 00 00 mov $0x1,%eax
14 Branch TRUE [B4]
0x1e: e9 00 00 00 00 jmpq 0x5
B2 (bV)[11, 18] . B4 dom B4 pred: B4 24 Label ?
0x23: 90 nop
0x24: 90 nop
0x25: 90 nop
0x26: 90 nop
0x27: 90 nop
28 Mul rax:i = (rax:i, rsi:i)
0x28: 0f af c6 imul %esi,%eax
32 Add rsi:i = (rsi:i, const[1|0x1]:i)
0x2b: 83 c6 01 add $0x1,%esi
34 XIR: safepoint() temp=(r14:j) [bci:18, refmap(rdi:a)]
0x2e: 4d 8b 36 mov (%r14),%r14
B4 (LHV)[4, 8] . B3 B2 dom B1 pred: B1 B2 16 Label ?
18 Cmp (rsi:i, const[1000|0x3e8]:i)
0x31: 81 fe e8 03 00 00 cmp $0x3e8,%esi
20 Branch < [B2]
0x37: 7c ef jl 0xfffffff1
B3 (V)[21, 28] dom B4 pred: B4 42 Label ?
move stack:1:a = rdi:a
0x39: 48 89 7c 24 08 mov %rdi,0x8(%rsp)
44 move rsi:a = const[staticTuple-System]:a
0x3e: 48 8b 35 00 00 00 00 mov 0x0(%rip),%rsi # 0x7
46 XIR: rcx:a = getfield<Object>(v5:a, const[24|0x18]:i) input=(rsi:a)
0x45: 48 8b 4e 18 mov 0x18(%rsi),%rcx
48 XIR: rdx:j = invokevirtual(v6:a, const[360|0x168]:i) method=java.io.PrintStream.println(int) input=(rcx:a) temp=(rsi:a, rdx:j) [bci:25, refmap(stack:1:a, rcx:a)]
0x49: 48 8b 31 mov (%rcx),%rsi
0x4c: 48 8b 96 68 01 00 00 mov 0x168(%rsi),%rdx
50 move rdi:a = rcx:a
0x53: 48 8b f9 mov %rcx,%rdi
52 move rsi:i = rax:i
0x56: 48 8b f0 mov %rax,%rsi
move stack:2:i = rax:i
0x59: 89 44 24 10 mov %eax,0x10(%rsp)
54 IndirectCall rdx:j(rdi:a, rsi:i) [bci:25, refmap(stack:1:a)]
0x5d: ff d2 callq *%rdx
0x5f: 90 nop
56 XIR: epilogue() method=Main.main(String[]) [bci:28, refmap(stack:1:a)]
0x60: 48 83 c4 28 add $0x28,%rsp
58 Return <illegal>
0x64: c3 retq
.
1 passed
Use mx olc -help
to see what other options mx olc
accepts.
Targeting different architectures¶
Offline compilation can also be used to target a different architecture than the host one. For instance, to target RISC-V we issue the following command:
mx --J @"-Dmax.platform=linux-riscv64" olc -cp ./ -c=C1X ^Main:main^
Maxine currently supports:
linux-amd64
linux-arm
linux-aarch64
linux-riscv64
Patterns¶
A pattern is a class name pattern followed by an optional method name pattern separated by a :
further followed by an optional signature:
<class name>[:<method name>[:<signature>]]
For example, the list of patterns:
"Object:wait", "String", "Util:add:(int,float)"
will match all methods in a class whose name contains “Object” where the method name contains “wait”, all methods in a class whose name contains “String” and all methods in any class whose name contains “Util”, the method name contains “add” and the signature is (int, float)
.
The type of matching performed for a given class/method name is determined by the position of ^
in the pattern name as follows:
Position of ^ |
Match algorithm |
---|---|
start AND end | Equality |
start | Prefix |
end | Suffix |
absent | Substring |
For example, ^java.util:^toString^
matches all methods named “toString” in any class whose name starts with “java.util”.
The matching performed on a signature is always a substring test. Signatures can be specified either in Java source syntax (e.g. “int,String”) or JVM internal syntax (e.g. “IFLjava/lang/String;”). The latter must always use fully qualified type names where as the former must not.
Any pattern starting with !
is an exclusion specification.
Any class or method whose name contains an exclusion string (the exclusion specification minus the leading !
) is excluded.