代码之家  ›  专栏  ›  技术社区  ›  Cheery

直接执行的编译器设计

  •  2
  • Cheery  · 技术社区  · 16 年前

    你知道什么时候好的编译器设计应该把输出放在进程内存中并在编译后立即执行吗?

    我查阅了一些SCHEME编译器,并尽可能地阅读了有关V8的内容。我想在自己的编译器中尝试一些有趣的JIT技术,比如内联缓存。

    答案很明显,比如利用在执行输出程序的同一地址空间中编译的事实。我对存储和链接程序的设计选择感兴趣。

    4 回复  |  直到 16 年前
        1
  •  1
  •   Carl Smotricz    16 年前

    部分相关: Principles of Artificial Intelligence Programming 在共同的口齿不清彼得诺维格。

    当然,在使用Lisps时,语言已经为您完成了许多“编译”工作。我不记得他创建了什么样的“可执行”代码,也许是某种CL字节码?

        2
  •  1
  •   David Thornley    16 年前

        3
  •  1
  •   Will Hartung    16 年前

    一旦你开始为泛型编译器生成代码,不管是哪种语言,谈论它几乎是一样的。不同语言的复杂性涉及到有效地处理语言中环境的语义(即Scheme有闭包和连续体之类的东西,而BASIC之类的东西没有)。

    但是,一旦您决定了这样的东西是如何表示的(有些会影响内存布局、可访问性等方面的效率),代码生成就很简单了。

    你所遇到的区别是,比如说,一个方案编译器编译成C,然后把它交给C编译器(C编译器可以把它编译成汇编程序,然后交给汇编程序),与你的编译器直接在RAM中生成机器指令的区别。

    不同的阶段为您提供了添加优化的机会,并提供了关注点的分离。生成C代码可能比生成汇编代码,尤其是机器代码更容易,因为C编译器可以为您做一些繁重的工作(比如体系结构的可移植性)。

    但是一些系统可以使用C来编译代码,这些代码通过动态链接过程立即加载并执行。

    最后,所有的数据都在RAM中的某个地方,不管这些数据是机器代码还是VM代码都是一个细节问题。该数组是在RAM中还是由VM从文件映射进来是另一个细节。有了虚拟内存,您的系统可能不在乎这种或那种方式。

    因此,它归结为专注于代码生成本身。一旦你习惯了,将它定向到其他编译器、RAM或文件是一个很小的步骤。

        4
  •  0
  •   Gian    16 年前

    在我看来,编译器的大部分工作都是在您选择正确的开始输出代码的位置时完成的。它是在磁盘上还是在进程空间中生成二进制文件,对于大多数编译器组件来说都是不可见的。您可以做的一件显而易见的事情是使用当前流程的分析信息来指导优化过程。

    另一个设计选择是要使它快速!如果是JIT,那么我认为你不想花很长时间等待。想必这可以指导您被迫做出的其他设计决策。我认为你不会后悔让你的编译器比其他限制更快。

    所以对我来说,最重要的一点是,你不需要太在意代码的最终去向,直到你真正把它放在那里。似乎没有理由同一个编译器不能在磁盘上生成普通的二进制文件,也不能输出到当前进程空间中的某个地方(适当地遵循正确的头和二进制格式)。