5

我是用 C# 制作的 psp 模拟器的作者。

我正在使用 ILGenerator 生成很多“DynamicMethod”。我正在将汇编代码转换为 AST,然后生成 IL 代码并构建该 DynamicMethod。我正在另一个线程中执行此操作,因此我可以在程序执行其他方法时生成新方法,以便它可以顺利运行。

我的问题是本机代码生成是惰性的,所以机器码是在调用函数时生成的,而不是在生成IL时生成的。所以它在程序执行线程中生成,本机代码生成非常慢,因为它是 asm->ast->il 步骤。

我已经尝试了 Marshal.Prelink 方法,它应该在执行函数之前生成机器代码。它适用于 Mono,但不适用于 MS .NET。

Marshal.Prelink(MethodInfo);

有没有办法在 MS .NET 上预链接 DynamicMethod?

我想为函数添加一个布尔参数,如果设置了该参数,则会立即退出函数,因此实际上不会执行任何代码。我可以通过这种方式“预链接”,但我认为这是我想避免的讨厌的解决方案。

任何想法?

4

2 回答 2

0

阅读有关其为何无法正常工作的信息,MSDN 文档说明如下:

在平台调用之外的方法上调用 Prelink 无效。

我很确信,如果你使用restrictedskipverificationor skipverification,它会跳过这个方法。

尽管如果我错了,您的短路想法也不错。

于 2013-01-12T18:52:53.270 回答
0

我发现有人说为动态方法创建委托会强制 JIT:

创建一个以方法为目标的委托。这有什么意义?

这听起来也很有希望:

Thread jitter = new Thread(() =>
{
  foreach (var type in Assembly.Load("MyHavyAssembly, Version=1.8.2008.8," + 
           " Culture=neutral, PublicKeyToken=8744b20f8da049e3").GetTypes())
  {
    foreach (var method in type.GetMethods(BindingFlags.DeclaredOnly | 
                        BindingFlags.NonPublic | 
                        BindingFlags.Public | BindingFlags.Instance | 
                        BindingFlags.Static))
    {
      System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(method.MethodHandle);
    }
  }
});
jitter.Priority = ThreadPriority.Lowest;
jitter.Start();
于 2012-12-01T04:59:05.980 回答