[mini] Initial tiered compilation work (mono/mono#17551)
authorBernhard Urban-Forster <lewurm@gmail.com>
Tue, 29 Oct 2019 21:36:01 +0000 (22:36 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Tue, 29 Oct 2019 21:36:01 +0000 (22:36 +0100)
commit4ce5a761eb93e9526bfbfb868f88a25261d5c4ce
tree9fa8ac071c2be8ef6fe850f1cd4e8f01f4ae6ce7
parentb9b2e41dc563e8cf07692fc263258884126db48d
[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
18 files changed:
src/mono/configure.ac
src/mono/mono/mini/Makefile.am.in
src/mono/mono/mini/interp/interp-internals.h
src/mono/mono/mini/interp/interp.c
src/mono/mono/mini/interp/mintops.def
src/mono/mono/mini/interp/mintops.h
src/mono/mono/mini/interp/transform.c
src/mono/mono/mini/mini-profiler.c
src/mono/mono/mini/mini-runtime.c
src/mono/mono/mini/mini.h
src/mono/mono/mini/tiered.c [new file with mode: 0644]
src/mono/mono/mini/tiered.h [new file with mode: 0644]
src/mono/mono/mini/trace.c
src/mono/mono/mini/trace.h
src/mono/mono/utils/mono-counters.c
src/mono/mono/utils/mono-counters.h
src/mono/mono/utils/mono-logger-internals.h
src/mono/mono/utils/mono-logger.c