调用方法句柄字段的最快方法

Fastest way to invoke method handle fields

我正在生成大致相当于 class 的字节码,例如:

final class MyCls {
  final MethodHandle handle1;
  final MethodHandle handle2;
  // and so on

  // This needs to invoke `handle1`, `handle2`, etc. in it somehow
  final static myMethod() {
    // ...
  }

}

class 的寿命相当长,我希望从其他方法内部调用 MethodHandles,理想情况下开销尽可能小。最好的方法是什么?想到的两个想法是:

句柄的签名会有所不同(尽管它们的使用站点都应该使用正确的签名 - 我可以 detect/enforce 在代码生成时)。

更新

这里有一些关于我实际工作的额外背景信息。 classes 表示已编译的 WASM 模块,方法句柄是导入的函数,class 的每个实例都在 WASM 模块的另一个实例中。

在这里不必使用 MethodHandle 来表示导入的函数 - 我也可以接受类似 java.util.function.Function 的东西,甚至可能只是一个虚拟方法调用。我 do 有时需要一个 MethodHandle 表示,但我也可以从虚拟方法中调用一个(我也可以实现一个手动调用 Function 的虚拟方法).

模块 class 实例本身可能最终存储在静态字段中,但不能保证。如果有 一种加速这种情况的方法,我可以推荐用户使用它。

简单的答案是只生成 invokeExact 个调用。使用您显示的代码形状,无需使用 invokedynamic (实际上这似乎不可能,因为 invokedynamic 调用 bootstrap 动态提供实现的方法)。

由于句柄是存储的实例字段,它们不被视为常量,因此调用会脱节,这会增加开销,并且由于缺乏内联而错失优化机会。

如果您真的希望它尽可能快,您需要为每个要使用的方法句柄组合生成一个新的 class,并将方法句柄存储在 static final 字段,或在常量池中(例如使用常量池修补,或隐藏 classes + class 数据 + 动态常量 [1]).