JIT 解释器如何处理变量名?
How do JIT interpreters handle variable names?
假设我要设计一个 JIT 解释器,在运行时将 IL 或字节码翻译成可执行指令。每次在代码中遇到变量名时,JIT 解释器都必须将其翻译成相应的内存地址,对吗?
JIT 解释器使用什么技术来以足够高效的方式解析变量引用?他们是否使用哈希,变量是否提前编译到地址,还是我完全遗漏了什么?
这个问题有很多种可能的答案,就像通常如何设计 JIT 有很多种答案一样。
但举一个例子,考虑 JVM。 Java 字节码实际上根本不包含变量名,除了 debugging/reflection 元数据。相反,编译器为每个变量分配一个从 0 到 65535 的 "index",字节码指令使用该索引。但是,如果 VM 愿意,它可以自由地进行进一步的优化。例如,它可以将所有内容转换为 SSA 形式,然后将其编译为机器代码,在这种情况下,变量最终将被转换为机器寄存器或堆栈帧中的固定偏移量,或者完全优化掉。
考虑另一个例子:CPython。 Python 由于其高级、灵活的特性,实际上在运行时维护变量名。然而,interperter 仍然执行一些优化。例如,具有 __slots__
属性的 类 将为字段分配一个固定大小的数组,并使用名称 -> 索引哈希映射进行动态查找。我不熟悉实现,但我认为它对局部变量做了类似的事情。请注意,正常的局部变量访问(不使用反射)可以在 "compile" 时间转换为固定偏移量。
简而言之,
的答案
Do they use hashing, are the variables compiled to addresses ahead of time, or am I missing something altogether?
是的。
假设我要设计一个 JIT 解释器,在运行时将 IL 或字节码翻译成可执行指令。每次在代码中遇到变量名时,JIT 解释器都必须将其翻译成相应的内存地址,对吗?
JIT 解释器使用什么技术来以足够高效的方式解析变量引用?他们是否使用哈希,变量是否提前编译到地址,还是我完全遗漏了什么?
这个问题有很多种可能的答案,就像通常如何设计 JIT 有很多种答案一样。
但举一个例子,考虑 JVM。 Java 字节码实际上根本不包含变量名,除了 debugging/reflection 元数据。相反,编译器为每个变量分配一个从 0 到 65535 的 "index",字节码指令使用该索引。但是,如果 VM 愿意,它可以自由地进行进一步的优化。例如,它可以将所有内容转换为 SSA 形式,然后将其编译为机器代码,在这种情况下,变量最终将被转换为机器寄存器或堆栈帧中的固定偏移量,或者完全优化掉。
考虑另一个例子:CPython。 Python 由于其高级、灵活的特性,实际上在运行时维护变量名。然而,interperter 仍然执行一些优化。例如,具有 __slots__
属性的 类 将为字段分配一个固定大小的数组,并使用名称 -> 索引哈希映射进行动态查找。我不熟悉实现,但我认为它对局部变量做了类似的事情。请注意,正常的局部变量访问(不使用反射)可以在 "compile" 时间转换为固定偏移量。
简而言之,
的答案Do they use hashing, are the variables compiled to addresses ahead of time, or am I missing something altogether?
是的。