1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
Mono Ahead Of Time Compiler
===========================
The Ahead of Time compilation feature in Mono allows Mono to
precompile assemblies to minimize JIT time, reduce memory
usage at runtime and increase the code sharing across multiple
running Mono application.
To precompile an assembly use the following command:
mono --aot -O=all assembly.exe
The `--aot' flag instructs Mono to ahead-of-time compile your
assembly, while the -O=all flag instructs Mono to use all the
available optimizations.
* Position Independent Code
---------------------------
On x86 and x86-64 the code generated by Ahead-of-Time compiled
images is position-independent code. This allows the same
precompiled image to be reused across multiple applications
without having different copies: this is the same way in which
ELF shared libraries work: the code produced can be relocated
to any address.
The implementation of Position Independent Code had a
performance impact on Ahead-of-Time compiled images but
compiler bootstraps are still faster than JIT-compiled images,
specially with all the new optimizations provided by the Mono
engine.
* How to support Position Independent Code in new Mono Ports
------------------------------------------------------------
Generated native code needs to reference various runtime
structures/functions whose address is only known at run
time. JITted code can simple embed the address into the native
code, but AOT code needs to do an indirection. This
indirection is done through a table called the Global Offset
Table (GOT), which is similar to the GOT table in the Elf
spec. When the runtime saves the AOT image, it saves some
information for each method describing the GOT table entries
used by that method. When loading a method from an AOT image,
the runtime will fill out the GOT entries needed by the
method.
* Computing the address of the GOT
Methods which need to access the GOT first need to compute its
address. On the x86 it is done by code like this:
call <IP + 5>
pop ebx
add <OFFSET TO GOT>, ebx
<save got addr to a register>
The variable representing the got is stored in
cfg->got_var. It is allways allocated to a global register to
prevent some problems with branches + basic blocks.
* Referencing GOT entries
Any time the native code needs to access some other runtime
structure/function (i.e. any time the backend calls
mono_add_patch_info ()), the code pointed by the patch needs
to load the value from the got. For example, instead of:
call <ABSOLUTE ADDR>
it needs to do:
call *<OFFSET>(<GOT REG>)
Here, the <OFFSET> can be 0, it will be fixed up by the AOT compiler.
For more examples on the changes required, see
svn diff -r 37739:38213 mini-x86.c
* The Precompiled File Format
-----------------------------
We use the native object format of the platform. That way it
is possible to reuse existing tools like objdump and the
dynamic loader. All we need is a working assembler, i.e. we
write out a text file which is then passed to gas (the gnu
assembler) to generate the object file.
The precompiled image is stored in a file next to the original
assembly that is precompiled with the native extension for a shared
library (on Linux its ".so" to the generated file).
For example: basic.exe -> basic.exe.so; corlib.dll -> corlib.dll.so
The following things are saved in the object file and can be
looked up using the equivalent to dlsym:
mono_assembly_guid
A copy of the assembly GUID.
mono_aot_version
The format of the AOT file format.
mono_aot_opt_flags
The optimizations flags used to build this
precompiled image.
method_infos
mono_icall_table
A table that lists all the internal calls
references by the precompiled image.
mono_image_table
A list of assemblies referenced by this AOT
module.
method_offsets
The equivalent to a procedure linkage table.
method_info_offsets
* Considerations
[ This section is outdated ]
[OUTDATED] All precompiled methods must be domain independent, or we add patch infos to
[OUTDATED] patch the target doamin.
[OUTDATED]
[OUTDATED] The main problem is how to patch runtime related addresses, for example:
[OUTDATED]
[OUTDATED] - current application domain
[OUTDATED] - string objects loaded with LDSTR
[OUTDATED] - address of MonoClass data
[OUTDATED] - static field offsets
[OUTDATED] - method addreses
[OUTDATED] - virtual function and interface slots
|