主要做了三层修改:
- 传播常量 Class mirror 的 Klass
当 Class.isInstance 被展开为:
load_klass_from_mirror(constant Class mirror)
现在编译器会通过新增的 VM callback 查询该 mirror 代表的 Klass,并把结果记录为常量元数据。普通类、接口和数组可以传播;primitive/void、非 Class 对象以及无法安全解析的情况不会传播。
- 在 TypeCheckElimination 中折叠检查
TypeCheckElimination 现在能从常量 mirror load 中提取目标 Klass,再结合 check_exact_klass 命中路径上已有的精确 receiver 类型,通过 IsSubtype 折叠 check_instanceof:
- receiver 与目标相同:
true
- receiver 是目标子类:
true
- 类型不兼容:
false
- 非常量 mirror:保持原检查
- primitive mirror/null:保留正确 Java 语义,不做不安全折叠
- 将折叠延后到 devirtualization/inline 之后
最初发现 mirror 折叠会在 PreCHACleanup 和 InlineDriver 循环中提前改变 CFG,进而干扰 receiver profile 和内联选择。因此现在这项特定折叠在以下阶段关闭:
- ProfileDevirtualization 之前
- InlineDriver 每轮固定点中
只在 inline/devirtualization 完成后的 cleanup 中开启。这样既删除 philosophers 中的两套动态 subtype CFG,又不改变第二 receiver 的内联收益模型。
对应三个阶段提交:
733a4000b3 fold constant Class mirror type checks
0787f87063 defer Class mirror folding until post-inline
fab3a0a95f keep mirror folding after devirtualization
主要做了三层修改:
当
Class.isInstance被展开为:现在编译器会通过新增的 VM callback 查询该 mirror 代表的
Klass,并把结果记录为常量元数据。普通类、接口和数组可以传播;primitive/void、非 Class 对象以及无法安全解析的情况不会传播。TypeCheckElimination现在能从常量 mirror load 中提取目标Klass,再结合check_exact_klass命中路径上已有的精确 receiver 类型,通过IsSubtype折叠check_instanceof:truetruefalse最初发现 mirror 折叠会在
PreCHACleanup和 InlineDriver 循环中提前改变 CFG,进而干扰 receiver profile 和内联选择。因此现在这项特定折叠在以下阶段关闭:只在 inline/devirtualization 完成后的 cleanup 中开启。这样既删除 philosophers 中的两套动态 subtype CFG,又不改变第二 receiver 的内联收益模型。
对应三个阶段提交: