Jvm JIT编译器如何领先于执行机器代码?

Jvm JIT编译器如何领先于执行机器代码?,jvm,executable,jit,machine-code,Jvm,Executable,Jit,Machine Code,如果我理解正确,JIT编译器会动态地将代码(通常是字节码)编译成本机代码,并将其插入到已知内存中的适当位置 一旦该过程启动,JIT编译器如何保持在正在执行的机器代码之前?如何确保正在执行的代码不会遇到空白内存,因为JIT还没有弄清楚下一步要放什么,所以在空白内存中使用了GOTO或等效代码 例如,给定一些伪字节码: 03 01 move variable 1 onto the stack b3 02 do something with the contents 在生成第一行本机代码并放入要运行的

如果我理解正确,JIT编译器会动态地将代码(通常是字节码)编译成本机代码,并将其插入到已知内存中的适当位置

一旦该过程启动,JIT编译器如何保持在正在执行的机器代码之前?如何确保正在执行的代码不会遇到空白内存,因为JIT还没有弄清楚下一步要放什么,所以在空白内存中使用了GOTO或等效代码

例如,给定一些伪字节码:

03 01 move variable 1 onto the stack
b3 02 do something with the contents

在生成第一行本机代码并放入要运行的下一行之后,我假设JIT将使本机代码转到一组空内存中,以便在其中运行下一批指令。但是,如果机器代码在JIT编译器有时间将第2行的机器代码放入该插槽之前到达那里,该怎么办?

这在特定的实现中有所不同。可能的策略是在解释器中运行代码,或者在分层JIT的情况下在上一个编译层中运行代码,同时编译或暂停执行,直到编译完成。

通过以下两个规则确保正确性:

绝不允许执行未完成的代码

JIT编译器将首先完成对其工作的任何代码区域的编译,这可能是一个基本块、一个函数或通过代码的任意跟踪。只有在完成后,它才允许处理器执行该代码。因此,执行过程中不会遇到未完成的翻译

不要生成未定义的跳转

每当JIT编译器遇到跳转,跳转离开正在编译的代码区域时,它将生成一个跳转回解释器代码,找出继续执行的位置,可能是通过编译其他代码区域,但绝不是未定义的位置。在编译区域的末尾也会执行同样的操作

一些JIT还编译成遵循机器调用约定的函数,因此可以只使用普通的返回LLVM JIT就是一个例子。在这种情况下,JIT代码只是通过函数指针调用的,代码只是返回给调用者,即解释器

其他JIT编译器为生成的代码生成自定义的序言和尾声,以确保处理器在执行JIT代码后处于定义的状态,并且继续执行所需的所有信息都可用


作为优化,JIT可能会注意到跳转到已经JIT编译或静态预编译的代码,例如库函数,并在那里发出直接跳转,或者,他们可以创建一条跳转指令,稍后可以对其进行修补,以转到新编译的代码段。QEMU会这样做。

本主题中的是否提供了详细信息?编译完成后才会运行正在编译的代码。一旦一个方法或另一个编译单元被完全编译,执行条目就会自动切换到一个新的编译版本。谢谢!这就是我要找的。