JIT code generation techniques虚拟机如何动态生成本机代码并执行它? 假设您可以弄清楚您要发出的本机操作码是什么,如何实际运行它? 是否像将助记符指令映射到二进制代码,将其填充到char *指针并将其强制转换为函数并执行一样,有点怪癖?
还是会生成一个临时共享库(.dll或.so或其他),然后使用 您可以使程序计数器指向您要执行的代码。请记住,数据可以是数据或代码。在x86上,程序计数器是EIP寄存器。 EIP的IP部分代表指令指针。调用JMP指令以跳转到一个地址。跳转后,EIP将包含此地址。
是。这是一种方法。结果代码将转换为C语言中的函数指针。
是的,如果您使用C或C ++(或类似的东西)来做,那正是您要做的。 看起来很黑,但这实际上是语言设计的产物。请记住,您要使用的实际算法非常简单:确定要使用的指令,将它们加载到内存中的缓冲区中,然后跳转到该缓冲区的开头。 但是,如果您确实尝试执行此操作,请确保在返回C程序时正确使用了调用约定。我想如果我想生成代码,我会寻找一个图书馆来照顾我。 Nanojit最近成为新闻。你可以看一下。 对。您只需构建一个char *并执行它。但是,您需要注意一些细节。 char *必须在内存的可执行部分中,并且必须具有正确的对齐方式。 除了nanojit之外,您还可以签出LLVM,这是另一个库,能够将各种程序表示形式编译为功能指针。它的界面整洁,生成的代码趋向于高效。
是的,那行得通。 要在Windows中执行此操作,必须将PAGE_EXECUTE_READWRITE设置为已分配的块:
关于生成DLL:为此需要额外的I / O,再加上链接,再加上生成DLL格式的复杂性,将使事情变得更加复杂,并且最重要的是,它们会破坏性能。此外,最后您仍然调用指向已加载代码的函数指针,因此... 关于"可执行部分"的要求,在POSIX系统上调用mprotect()可以修复权限(Win32上有类似的API)。您需要对较大的内存段执行此操作,而不是对每个方法都执行一次,否则会太慢。 在纯x86上,您不会注意到该问题,在具有PAE或64位AMD64 / Intel 64位计算机的x86上,您会遇到段错误。 除了Rotor 2.0之外,您还可以查看OpenJDK中的HotSpot虚拟机。 据我所知,它必须编译内存中的所有内容,因为它必须运行一些试探法来优化代码(即:随着时间的推移而内联),但是您可以看看Shared Source Common Language Infrastructure 2.0转子版本。整个代码库与.NET相同,除了抖动和GC。 |