[mini] Initial tiered compilation work (mono/mono#17551)
[mini] Initial tiered compilation work
Enable it with `./autogen.sh --enable-experiment=tiered`.
Let's consider `Simple.cs`:
```csharp
using System.Runtime.CompilerServices;
using System;
public class Simple {
public static void Main (string []args) {
HotMethod ();
Console.WriteLine ("cnt: " + cnt);
HotMethod ();
Console.WriteLine ("cnt: " + cnt);
}
static int cnt = 0;
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void HotMethod () {
for (int i = 0; i <= 1000; i++)
cnt += i;
}
}
```
```console
$ csc Simple.cs
$ MONO_LOG_LEVEL=debug MONO_LOG_MASK=tiered ./mono/mini/mono-sgen --trace=M:Simple:HotMethod --interp=-all Simple.exe
[0x10ec275c0: 0.00000 0] ENTER:i Simple:HotMethod ()()
Mono: tiered: queued Simple:HotMethod ()
[0x10ec275c0: 0.00010 0] LEAVE:i Simple:HotMethod ()(
Mono: tiered: patching 0x7fe855803224 with patch_kind=INTERP @ tier_level=0
Mono: -> caller= Simple:Main (string[]) [{0x7fe85420df88} + 0x34 interp] (0x7fe8558031f0 0x7fe855803258) [0x7fe85420c880 - Simple.exe]
Mono: -> callee=Simple:HotMethod ()
Mono: tiered: patching 0x7fe8558031f2 with patch_kind=INTERP @ tier_level=0
Mono: -> caller= Simple:Main (string[]) [{0x7fe85420df88} + 0x2 interp] (0x7fe8558031f0 0x7fe855803258) [0x7fe85420c880 - Simple.exe]
Mono: -> callee=Simple:HotMethod ()
cnt: 500500
[0x10ec275c0: 0.04093 0] ENTER:c Simple:HotMethod ()()
[0x10ec275c0: 0.04095 0] LEAVE:c Simple:HotMethod ()(
cnt: 1001000
```
Note the suffix after `ENTER:`
* `i` indicates it's executed by the interpreter
* `c` indicates it's a compiled method (JIT)
Another example:
```console
$ make -C mono/mini gshared.exe
$ ./mono/mini/mono-sgen --interp=-all --stats ./mono/mini/gshared.exe
Regression tests: 84 ran, 0 failed in Tests
[...]
Tiered statistics
Methods promoted : 68
```
It's a basic proof-of-concept for now. An incomplete list of future work items:
* Right now it only works for direct calls, need to expand it to virtual/interface calls.
* Calls of the JIT leading into the interpreter again can't be patched yet.
* Kind of related, no concept of versioning compiled methods does exist yet. The interpreter maintains its own table of "transformed" methods, however, when doing the transition from JIT->interpreter, the wrapper+interpmethod will end up in the JIT table. We need a way to have multiple JIT compilation results for the same MonoMethod exist.
* Investigate actual performance. We might have to optimize the interp<>JIT transition.
* Patching is racy. Need to make that atomic.
* All the FIXMEs in this PR
<!--
Thank you for your Pull Request!
If you are new to contributing to Mono, please try to do your best at conforming to our coding guidelines http://www.mono-project.com/community/contributing/coding-guidelines/ but don't worry if you get something wrong. One of the project members will help you to get things landed.
Does your pull request fix any of the existing issues? Please use the following format: Fixes #issue-number
-->
Commit migrated from https://github.com/mono/mono/commit/
d274cfbacdb2aeab0184662997882f3d78991e48