背景
我目前正在用 C# 编写 JVM,纯粹出于学术目的(也许将来会构建混合的 .NET 和 Java/Scala 应用程序)。
上下文
我编写了简单的JAVA类:
public class test
{
public static String hello_world(int i)
{
return "Hello " + i + " World!";
}
}
并将其编译为test.class
。
当我使用反编译器(我将其编写为 JVM 的一部分)对其进行反编译时,我看到此方法的以下说明:
iload_0
invokedynamic 2
areturn
当在常量池中查找索引 2
处的常量时,我看到一个包含以下数据的 InvokeDynamic-Constant 条目:
makeConcatWithConstants : (I)Ljava/lang/String;
我想这是有道理的(我更多的是 .NET 用户而不是 JAVA 用户)。
当使用参数1
执行我的方法hello_world
时,在执行invokedynamic 2
之前我有以下堆栈:
----TOP---
0x00000001
--BOTTOM--
问题
我的问题是:如何使用invokedynamic
?
我无法解析方法 makeConcatWithConstants
,因为 InvokeDynamic-Constant 没有给我任何提示,其中 makeConcatWithConstants
可能位于( see documentation )。
堆栈也不包含对堆的引用,指示方法 makeConcatWithConstants
可以与哪个实例类型关联。
我通读了the invokedynamic
docs但我不明白(也许我被.NET-Framework“伤害”太多了)。
有人能给我举一些关于执行这三个指令时 JVM 内部发生的事情的示例吗? (invokedynamic
的被调用者期望什么等)?
我已经在我的 JVM 中实现了 invokestatic
...但我目前无法理解 invokedynamic
。
最佳答案
invokedynamic
的想法是;当第一次遇到此字节码时,调用一个引导方法,该方法创建一个 Callsite
对象,该对象链接到需要调用的实际方法。
实际上,这通常意味着您动态创建调用的实现。
如果您使用 javap -v test
查看程序,您将在底部看到一个 BootstrapMethods
属性:
BootstrapMethods:
0: #15 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
Method arguments:
#16 Hello \u0001 World!
您可以在其中看到此特定调用站点的引导方法位于 StringConcatFactory
方法参数
是一组常量参数。
Lookup
的主要论点、字符串
和 MethodType
分别是;与调用点具有相同权限、某些名称和调用点类型的查找对象。其中第一个需要由VM在运行时提供,后两个由invokedynamic常量池条目以名称和类型的形式提供:
#2 = InvokeDynamic #0:#17 // #0:makeConcatWithConstants:(I)Ljava/lang/String;
因此,要实现此字节码,您必须有一些机制来创建查找对象,然后能够调用引导方法。之后,您可以对返回的 Callsite
调用 dynamicInvoker()
对象,它给你一个 MethodHandle
然后您应该缓存这个特定的调用站点,然后(最后)调用。
如果您想了解 OpenJDK 中的实现方式,您可以在此处找到实现:http://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/interpreter/bytecodeInterpreter.cpp#l2446
我猜这在项目的早期阶段可能太棘手了,所以现在使用 -XDstringConcat=inline
编译程序可能会更容易,因为它使用旧版 StringBuilder
连接,应该更容易实现。
关于java - 使用 "invokedynamic"- 幕后发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53139737/