【问题标题】:How can a JVM be written in Java如何用 Java 编写 JVM
【发布时间】:2011-01-17 18:21:16
【问题描述】:

我正在简要阅读Maxine,这是一个用 Java 编写的开源 JVM 实现。这对我来说听起来很循环。如果java需要虚拟机运行,那么虚拟机本身如何用Java编写(虚拟机代码不会需要虚拟机运行吗?等等)。

编辑:好的,所以我发现我忽略了 Java 不必在 VM 中运行的事实。那么如何解释如何用 LISP 编写 LISP 编译器呢?还是应该完全是一个新问题?

【问题讨论】:

  • Bjarne Stroustroup 不是第一个用 C++ 编写的 C++ 编译器(当时它还被称为“带类的 C”)?我认为这更令人印象深刻,因为 C++ 不是解释语言,但需要编译器!
  • 这正是我不明白的:)
  • 新龙之书,第一版(远离充满错误的第二版)解释了编译器引导。
  • 在极端情况下,您可以用 Java 编写汇编器和链接器(汇编器没有什么神奇之处)。您可以用 Java 为 Java 源代码编写解析器。您可以基于生成程序集的新解析器编写编译器,您可以使用汇编器和链接器将其组装并链接到本机可执行文件。

标签: java jvm bootstrapping


【解决方案1】:

您一开始就认为 Java 需要虚拟机是不正确的。查看项目GCJ: The GNU Compiler for the Java Programming Language

【讨论】:

  • java 语言可能不需要虚拟机,但术语“java”不仅涵盖语言,还包括虚拟机。
  • 而且 Maxine 至少似乎需要 JDK1.6 JVM 才能在其上运行。
  • @kji:我想我错了。似乎 Maxine 确实编译为本机可执行文件,因此在最初构建 Maxine 后不需要 JDK JVM(我相信它仍然需要类库)。
【解决方案2】:

Java 代码可以直接编译成机器码,这样就不需要虚拟机了。

【讨论】:

    【解决方案3】:

    您可以查看完善的引导编译器的方法。我认为它始于 70 年代...

    【讨论】:

      【解决方案4】:

      您需要引导用 Java 编写的 JVM 的 JVM 可能不需要很多功能(例如垃圾收集和 JIT),可能非常简单。然后,所有更高级的功能都可以用 Java 实现(这似乎正是 Maxine 的目的,以试验 JVM 技术中的新想法)。

      此外,Maxine 确实包含 C 代码,我猜它构成了一个最小的运行时环境,用于让 Maxine 的其余部分运行。我认为有趣的部分(JIT 编译器、垃圾收集)随后完全用 Java 实现。

      【讨论】:

      • 不。 Maxine 中的 C 代码更像是一种数据定义语言,它实际上并没有实现任何有趣的东西。操作系统希望某些结构以某种特定方式在内存中布局,而 C 编译器知道如何做到这一点,因此 Maxine 使用 C 来正确布局这些结构。但是只有少数地方使用了 C:一个最小的启动器,它将 VM 映像加载到内存中,将加载地址写入映像内部的特定位置,然后跳转到另一个特定位置。调试器,因为 Maxine 使用操作系统的 C 调试工具。
      • JNI 的低级部分,因为 JNI 的重点是与 C 集成。以及线程的低级部分,因为 Maxine 使用与系统大不相同的本地线程到系统。
      • @Jörg W Mittag:那么,Maxine 是否仍然运行正常的 JVM?正在加载的 VM 映像是本机二进制文件,对吗?它是如何创建的?
      • 所有现代 JVM 都有一个 JIT 编译器,它将 JVM 字节码编译为本机机器码。通常,只有代码的“热”部分正在编译(其余部分正在解释),通常,代码保存在内存中并在程序退出时被丢弃。但是没有理由不能 JIT 编译 所有 代码,也没有理由不能将代码写入磁盘,这正是 Maxine 所做的。例如,Oracle 的 JRockijt JVM 和 Google 的 V8 JavaScript 编译器也将编译后的本机代码保存在磁盘上,尽管在他们的情况下这只是出于缓存原因。
      【解决方案5】:

      【讨论】:

        【解决方案6】:

        【讨论】:

          【解决方案7】:

          这有点像“哇哦,伙计,这怎么行???” - 但我认为您正在描述被称为“自托管”的现象:

          语言(或工具链/平台)一开始并不是自托管的——它们开始时是在现有平台上构建的:在某一点上,它们变得足够实用,可以编写理解语法的程序它本身恰好是写在其中的。

          在经典的 AWK 书中有一个很好的例子,它介绍了一个 AWK 程序,它可以解析(一个缩减版)其他 AWK 程序:请参见下面的链接。

          《美丽的代码》一书中还有一个例子,它有一个可以解析Javascript的Javascript程序。

          我认为要记住这一点 - 如果您(比如说)有一个用 Java 编写的 JVM,因此可以运行 Java 字节码:运行 Java JVM 本身的 JVM 必须本地托管(也许这个 JVM 是编写的在'C'中,然后编译为机器代码):在任何情况下最终都是自托管程序 - 沿着这条线的某个地方。

          所以谜团被揭开——因为在某些时候,所有东西下面都会运行一个本机机器代码程序。

          这有点相当于能够使用英语本身来描述英语(等)语言......也许......

          http://www.amazon.co.uk/AWK-Programming-Language-Alfred-Aho/dp/020107981X/ref=sr_1_fkmr0_3?ie=UTF8&qid=1266397076&sr=8-3-fkmr0

          http://www.amazon.co.uk/gp/search/ref=a9_sc_1?rh=i%3Astripbooks%2Ck%3Abeautiful+code&keywords=beautiful+code&ie=UTF8&qid=1266397435

          http://en.wikipedia.org/wiki/Self-hosting

          【讨论】:

            【解决方案8】:

            上周我看了 Maxine 并且想知道同样的问题 :)

            来自 Maxine documentation

            1 构建启动映像

            现在让我们构建一个[启动映像]。在 这一步,Maxine 在主机 JVM 上运行 配置原型,然后 编译自己的代码和数据 创建一个可执行程序 目标平台。

            2 运行 Maxine

            现在 Maxine 已经编译了自己, 我们可以将它作为标准的 Java VM 运行。 max vm 命令处理细节 类和库路径和 提供了一个类似于 标准的 java 启动器命令。

            【讨论】:

              【解决方案9】:

              我知道这篇文章很旧,但我想我可能会在讨论中添加一些内容,因为它们是被遗漏的要点。所以未来的读者可能会觉得这很有帮助。

              我想知道是否每个人都错过了这里的重点。您可以用几乎任何语言编写几乎任何类型的编译器、解释器或虚拟机。当使用 C 编写 C 编译器时,需要 C 编译器来编译新的编译器。但是,输出是在指定平台上运行的本机代码。仅仅因为 JVM 是用在 JVM 上运行的语言编写的,并不意味着输出必须产生在 JVM 上运行的代码。例如,您可以用 Java 编写 C、Basic、Pascal 编译器甚至汇编程序。在这种情况下,您将需要 JVM 来创建编译器或汇编器,但一旦创建,如果初始代码生成本机代码,您可能不再需要 JVM。另一种方法是编写一个翻译器,将输入语言转换为本地机器语言,这样您就可以用语言 A 编写程序,然后将其编译成语言 B,然后再编译成机器代码。在微控制器世界中,您经常看到这一点。有人想用 Basic 或 Java 编写程序,所以他们编写 Basic/Java 编译器来为现有的 C 编译器生成 C 代码。然后将生成的 C 代码编译成提供本地 Basic/Java 编译器的机器语言。这种方法通常比直接用机器码编写 Basic/Java 编译器更容易。

              多年前,我编写了 BasicA 和 GWBasic 程序,它们为 6800 和 Z80 微控制器生成汇编代码。我的观点是,输出不必与输入或目标相同。 IE。仅仅因为您使用 Java 编写 JVM 并不意味着最终结果必须在 Java JVM 下运行。

              【讨论】:

                【解决方案10】:

                这是一篇关于引导自托管 VM 的好论文。不是Java,而是javascript,但原理是一样的。

                Bootstrapping a self-hosted research virtual machine for JavaScript: an experience report

                请注意,虽然引导自托管编译器和引导自托管 VM 有点相似,但我相信它们不会引发完全相同的挑战。

                【讨论】:

                  猜你喜欢
                  • 2010-11-16
                  • 1970-01-01
                  • 2011-04-12
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-03-29
                  • 2013-04-03
                  • 2011-03-27
                  • 1970-01-01
                  相关资源
                  最近更新 更多