为了支持动态类型和方法分派,我的编程语言引入了一种名为dynamic
. 在调用类型为 的被调用者上的方法时dynamic
,编译器首先将被调用者和所有参数压入堆栈,然后生成一条invokedynamic
指令而不是普通invoke*
指令。该指令指向一个名为 的类中的特殊引导方法DynamicLinker
,但在调用它时只有静态类型可用。
我的问题:如何获取传递给invokedynamic
指令的参数的运行时类型?
为了支持动态类型和方法分派,我的编程语言引入了一种名为dynamic
. 在调用类型为 的被调用者上的方法时dynamic
,编译器首先将被调用者和所有参数压入堆栈,然后生成一条invokedynamic
指令而不是普通invoke*
指令。该指令指向一个名为 的类中的特殊引导方法DynamicLinker
,但在调用它时只有静态类型可用。
我的问题:如何获取传递给invokedynamic
指令的参数的运行时类型?
的“动态”部分invokedynamic
并不意味着方法参数可以具有动态类型。相反,这意味着invoke
可以自定义指令的行为。参数的确切类型invokedynamic
在编译时是已知的。
重点invokedynamic
不是 JVM 将实现动态类型系统。这将是一个巨大的变化,会影响 JVM 的许多部分,并且即使在不使用该功能的地方也可能导致性能下降,而收益却很小:毕竟,每种动态语言都有不同的类型系统概念。
相反,invokedynamic
允许您实现动态类型系统。您可以做 JVM 和热点优化器所做的事情,但使用您自己的语义。所以你正在实现一个动态方法调用调度程序,就像你没有invokedynamic
. 在第一次调用时,您将链接到该动态调度程序,该调度程序将使用参数的运行时类型来查找目标。但它也可能会记录目标,如果它发现特定调用站点具有单态行为,它的目标可能会被重定向到优化的调度程序,甚至直接到目标方法,这取决于您如何防止以后的更改行为。例如,如果运行时将检测到相关不变量的失效,例如通过将新类型加载到运行时中,您可以将调用站点直接链接到目标并在使目标失效的事件发生时(再次)更改目标。或者您将调用定向到一个标记代码,该代码在执行优化调用之前检查其先决条件,
如前所述,这与优化技术类似,JVM 将自身用于承载 Java 语义的调用。但是您可以控制现有的调用类型以及如何解决它们。当然,你可以在没有invokedynamic
指令的情况下实现所有这些,使用对你的类型系统建模的普通对象结构,但是,invokedynamic
指令允许你告诉 JVM 调用者和被调用者的语义,然后 HotSpot 优化器可以使用这些语义来进行直接它们之间的联系。