【问题标题】:How does JIT replace optimized machine code during runtime?JIT 如何在运行时替换优化的机器代码?
【发布时间】:2011-02-19 17:25:46
【问题描述】:

我正在浏览 OpenJDK 源代码,但找不到替换优化代码的地方。

我想知道如何在保护模式下做到这一点,这不是操作系统应该阻止的某种自我修改代码吗?

【问题讨论】:

    标签: java optimization assembly jit


    【解决方案1】:

    “JITer”在堆或堆栈中分配空间并将汇编代码插入其中。不,自我修改代码非常好。 VirtualProtect (Windows) 和 mmap (Unix) 可以将页面映射为可执行文件。默认情况下,通用操作系统会将可执行页面标记为读/执行但不写,您通常仍然可以在运行时更改此设置。

    如果无法修改代码,就无法加载 dll,除非将其加载到固定的虚拟地址并共享到每个进程的地址空间中;那么你会得到地址空间地狱而不是 dll 地狱。

    我猜你听说过 NX 位或 DEP 等,它们只是保护你免于执行不可执行的代码,这有助于防止堆栈溢出等。

    【讨论】:

    • 很久没有搞过自修改了,但只是为了确定:NX 位设置不会阻止 NX 允许自修改的内存部分?
    • @WizardOfOdds:NX 位可以在页表条目中设置。如果指令指针到达设置了它的页面,它只是告诉处理器引发页面错误。 Windows 允许您将页面标记为不可执行,但我认为它实际上不会在 x86 上执行任何操作,除非它是支持 NX 位(所有现代处理器)的处理器。
    【解决方案2】:

    JIT 代码不会替代优化的机器代码;它替换了加载的 Java 字节码。我不知道这是如何在 OpenJDK 中实现的,但通常情况下,JVM 会加载字节码并将其保存在某种形式的内部结构中,通常在具有用于执行代码的一个或多个虚拟函数的类中。当它被即时编译时,指向该内部结构的指针被指向具有相同接口的类的指针替换,其中底层表示是本机机器代码而不是Java字节码,并且虚拟方法是这样实现的他们调用本机代码而不是解释字节码。没有修改代码,只是指向不同的地方。

    【讨论】:

    • 好吧,由于自适应优化,JIT 可以重新优化机器代码。在这种情况下,它可能会丢弃旧的优化机器代码并为新代码分配一个新块并替换指向它的指针。
    猜你喜欢
    • 2015-02-22
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多