及时编译的外部函数接口:它是什么被“运行时”编译的?

3

我的问题是关于外部函数接口的JIT编译,但我会以LuaJIT为例。据说LuaJIT的FFI比直接绑定到C更快,因为对C函数的调用可以被JIT编译。

有人能解释一下吗?通常,被绑定的C函数已经存在于库中,所以它已经被编译过了,那么究竟什么被JIT编译了呢?

1个回答

3

LuaJIT扩展:FFI库

[...] JIT编译器为从Lua代码访问C数据结构生成的代码与C编译器生成的代码相当。与通过经典的Lua/C API绑定的函数调用不同,C函数的调用可以在JIT编译的代码中内联。

针对您关于哪些内容会被编译的问题,只有对C函数的调用会被编译。实际上,通过经典的C API调用C函数永远不会被编译,即使在将来的LuaJIT版本中也是如此。它们会引发NYI消息,导致任何跟踪都会中止并有效地防止周围的Lua代码被编译。例如,在循环中的经典C函数调用FUNCC操作码将阻止该循环被编译。这意味着LuaJIT将回退到其解释器,但解释器仍然非常快。

重申一下,LuaJIT并不对已编译的C代码进行任何魔法操作。它只是在JIT汇编代码中内联FFI调用C函数。

在解释器中,它仍然是从C到C的函数调用,因此不会太昂贵,对吧?还是说LuaJIT也编译了一些提供额外好处的周围代码。在“内联FFI调用”中,它没有内联C函数,对吧,如果没有源代码那将是困难的。 - san
LuaJIT解释器是为其支持的每种不同架构手写汇编的。基本上,从解释器到JIT编译器的转换是从汇编和一些C到针对您的Lua代码进行优化的汇编,任何引发NYI标志的内容都将阻止这种转换。关于此事在LuaJIT网站以及源代码中有更多信息。您可能想尝试使用luajit -jdump来查看它生成了什么并了解编译器的工作方式。 - Ryan Stein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接