调用方法句柄字段的最快方法
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 的寿命相当长,我希望从其他方法内部调用 MethodHandle
s,理想情况下开销尽可能小。最好的方法是什么?想到的两个想法是:
- 在字段上生成显式
MethodHandle.invokeExact
调用
- 以某种方式使用
invokedynamic
(虽然我认为我仍然需要 exactInvoker
?)
句柄的签名会有所不同(尽管它们的使用站点都应该使用正确的签名 - 我可以 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]).
我正在生成大致相当于 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 的寿命相当长,我希望从其他方法内部调用 MethodHandle
s,理想情况下开销尽可能小。最好的方法是什么?想到的两个想法是:
- 在字段上生成显式
MethodHandle.invokeExact
调用 - 以某种方式使用
invokedynamic
(虽然我认为我仍然需要exactInvoker
?)
句柄的签名会有所不同(尽管它们的使用站点都应该使用正确的签名 - 我可以 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]).