为什么在JVM中隐藏JIT编译器没有基础设施?

Etk*_*tki 2 java jit jvm

我正在审查一个触及JIT内联语义的会议演示文稿,其中作者固定了奇怪的行为(当然,只有初看起来很奇怪) - C2比C1慢,因为由于内嵌深度过大而无法内联方法.它可以在以下示例中表示:

public static int multipleByTwo(int x) {
    return x * 2;
}

public static void entrypoint() {
    int sum = 0;
    for (int i = 0; i < 10_000_000; i++) {
        // due to some arbitrary cause, multiplyByTwo doesn't get inlined
        sum += multiplyByTwo(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

作为一名程序员,我可能知道有一个编译器不知道的优化领域.例如,如果multiplyByTwo强制内联,则可以进行大量优化,但由于各种约束(例如方法大小或内联深度),可以省略内联.为什么没有办法告诉编译器"嘿,我很确定你应该更喜欢内联那个方法而不是"?我敢肯定,我不是第一个考虑这个问题的人,并且讨论导致没有实现这样的功能 - 为什么?

ps请注意我正在谈论提示而不是指令; 我明白后一种选择会带来更多的伤害而不是利益.

apa*_*gin 10

实际上,一个控制HotSpot JVM编译器的基础设施.

1.编译器命令文件

您可以使用-XX:CompileCommandFile=JVM选项指定包含编译器命令的文件.有一些命令强制内联,从编译中排除方法,设置每方法选项(例如MaxNodeLimit)等等.可以在此处找到可用命令的完整列表.

编译器命令文件的示例可能如下所示

inline java.util.ArrayList::add
exclude *::<clinit>
print com.example.MyClass::*
Run Code Online (Sandbox Code Playgroud)

2.注释

JDK特定的注释是控制JVM优化的另一种方法.HotSpot JVM知道某些注释,例如

注意:所有这些机制都是非标准的.它们仅适用于OpenJDK和Oracle JDK.没有标准的方法来提示JVM编译器,因为有许多JVM实现具有完全不同的编译策略.特别是,有些JVM根本没有JIT编译.