When/Where PyPy 会产生机器码吗?
When/Where does PyPy produce machine code?
我浏览了 PyPy implementation details 并浏览了源代码,但 PyPy 的执行路径对我来说仍然不是很清楚。
有时会产生字节码,有时会跳过直接编译机器码(解释器level/app级代码),但我无法弄清楚机器码是何时何地产生的,是通过低级指令 (RAM/CPU) 交给 OS 进行二进制执行。
在 CPython 的情况下,我设法弄清楚了这一点,因为 ceval.c
中有一个巨大的开关 - 已经编译 - 它解释字节码并运行相应的代码(实际上在实际的 C 中)。有道理。
但就 PyPy 而言,我没有弄清楚这是如何完成的,具体来说(我不想深入了解 PyPy 的各种优化细节,那不是什么我在后面)。
我会对指向 PYPY 源代码的答案感到满意,这样可以避免“道听途说”并能够“亲眼看到”(我发现了 JIT 后端部分,在 /rpython 下,各种 CPU 架构汇编器)
你最好的向导是 pypy architecture documentation, and the actual JIT documentation。
最让我印象深刻的是:
we have a tracing JIT that traces the interpreter written in RPython, rather than the user program that it interprets.
这在 JIT overview 中有更详细的介绍。
好像“核心”是这个(来自here):
Once the meta-interpreter has verified that it has traced a loop, it decides how to compile what it has. There is an optional optimization phase between these actions which is covered future down this page. The backend converts the trace operations into assembly for the particular machine. It then hands the compiled loop back to the frontend. The next time the loop is seen in application code, the optimized assembly can be run instead of the normal interpreter.
This paper (PDF) 也可能有帮助。
编辑: 查看x86后端rpython/jit/backend/x86/rx86.py
,后端不编译而是直接吐出机器代码。查看 X86_64_CodeBuilder
和 AbstractX86CodeBuilder
class。更高一层是rpython/jit/backend/x86/assembler.py
中的Assembler386
class。该汇编程序使用 rpython/jit/backend/x86/codebuf.py
中的 MachineCodeBlockWrapper
,它基于 x86-64 的 X86_64_CodeBuilder
。
我浏览了 PyPy implementation details 并浏览了源代码,但 PyPy 的执行路径对我来说仍然不是很清楚。
有时会产生字节码,有时会跳过直接编译机器码(解释器level/app级代码),但我无法弄清楚机器码是何时何地产生的,是通过低级指令 (RAM/CPU) 交给 OS 进行二进制执行。
在 CPython 的情况下,我设法弄清楚了这一点,因为 ceval.c
中有一个巨大的开关 - 已经编译 - 它解释字节码并运行相应的代码(实际上在实际的 C 中)。有道理。
但就 PyPy 而言,我没有弄清楚这是如何完成的,具体来说(我不想深入了解 PyPy 的各种优化细节,那不是什么我在后面)。
我会对指向 PYPY 源代码的答案感到满意,这样可以避免“道听途说”并能够“亲眼看到”(我发现了 JIT 后端部分,在 /rpython 下,各种 CPU 架构汇编器)
你最好的向导是 pypy architecture documentation, and the actual JIT documentation。
最让我印象深刻的是:
we have a tracing JIT that traces the interpreter written in RPython, rather than the user program that it interprets.
这在 JIT overview 中有更详细的介绍。
好像“核心”是这个(来自here):
Once the meta-interpreter has verified that it has traced a loop, it decides how to compile what it has. There is an optional optimization phase between these actions which is covered future down this page. The backend converts the trace operations into assembly for the particular machine. It then hands the compiled loop back to the frontend. The next time the loop is seen in application code, the optimized assembly can be run instead of the normal interpreter.
This paper (PDF) 也可能有帮助。
编辑: 查看x86后端rpython/jit/backend/x86/rx86.py
,后端不编译而是直接吐出机器代码。查看 X86_64_CodeBuilder
和 AbstractX86CodeBuilder
class。更高一层是rpython/jit/backend/x86/assembler.py
中的Assembler386
class。该汇编程序使用 rpython/jit/backend/x86/codebuf.py
中的 MachineCodeBlockWrapper
,它基于 x86-64 的 X86_64_CodeBuilder
。