[Mono-dev] Paid mono hacking: Make AOT generate all code ahead of time

Joachim Ante joe at unity3d.com
Thu Jun 5 07:27:50 EDT 2008

>> The current AOT code does generate shared libraries, but all the
>> methods are in
>> a giant array named 'methods', we resolve its address using dlsym
>> (), then
>> add offsets to it to get the addresses of the code for the individual
>> methods. Is
>> there a device were this will not work ?
> That sounds good. Thanks for the heads up.
> It seems like we misunderstood something in the AOT then.
That makes things quite a bit easier.

Here is some information from Paolo on how complete AOTing of all  
functions can  be implemented:
Anyone who is interested in a contract job for implementing this,  
drop me a mail.


I'll list the steps that are needed to implement this.

1) you need a complete test suite of all the code that you'll need to
run, since there are many codepaths involved
2) add asserts in the mono_code_mananger() so you're sure they are not
3) aot corlib and all the other needed assemblies
4) run the test suite programs and fix the issues as they come up

To do 4 the general rule is: each reference to a runtime value
needs to be replaced in the generated code to a reference to an
array element. When you'll load the code, before executing it you will
set the array element to the expected runtime value. To do this you will
need to save in the aot file also a description of what goes inside each
array element.

Let's consider mono_arch_create_trampoline_code() in tramp-arm.c:
you'll need to change the function so that the code is emitted into the
aot file (or at least have it return the generated size, since in this
particular case it is position independent). After that you'll note that
currently the runtime addresses of mono_get_lmf_addr and of
mono_get_trampoline_func (tramp_type) are embedded in the code: you will
need to allocate slots in the mentioned array and change the generated
code to load the values from the array instead of from the constant pool
in the generated code.

A note about the array: this should be quick to access and the access
itself may not use runtime values. I don't know if OSX on ARM provides
fast access to tls data (and even if it does if it gives any guarantee
about future compatibility). Anyway, that would be the best choice. An
alternative is to reserve a global register for it (you will need to  
that register from the list of registers available to the register
allocator and you will need to set the register at each entrance to
managed code).
The array can be fixed-size (but then you are limited or you'll use much
more memory) or it can be extensible (make sure the deallocation is
thread safe or use a design similar to the one I implemented for managed
ThreadStatic slots).

There are many places in the jit and runtime code where runtime values
are embedded as constants in the generated code: most are in mini- 
and in metadata/marshal.c.

After all the trampolines and similar snippets of code are converted to
run under AOT there are still other methods that are currently created
and jitted at runtime. Using the test suite I mentioned above you will
need to get a list of them and pregenerate them in the AOT files as
well. This includes the methods used to perform the unmanaged->managed
transitions (those used to invoke Main() or to invoke the Finalizer
method in the finalizer thread and so on).

You will likely also need to change the values that are used to
implement interface method calls: currently it is a MonoMethod*.
You'd need to assign and keep track of the IDs there.

More information about the Mono-devel-list mailing list