unk*_*656 2 java jvm invokedynamic jvm-bytecode
我目前正在用 C# 编写 JVM,纯粹出于学术目的(也许将来会构建混合的 .NET 和 Java/Scala 应用程序)。
我写了一个简单的JAVA类:
public class test
{
public static String hello_world(int i)
{
return "Hello " + i + " World!";
}
}
Run Code Online (Sandbox Code Playgroud)
并将其编译成test.class. 当我使用反编译器(我将其编写为 JVM 的一部分)对其进行反编译时,我看到此方法的以下说明:
iload_0
invokedynamic 2
areturn
Run Code Online (Sandbox Code Playgroud)
当在常量池中查找索引处的常量时2,我看到一个包含以下数据的 InvokeDynamic-Constant 条目:
makeConcatWithConstants : (I)Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)
我想这是有道理的(我更像是 .NET 用户而不是 JAVA 用户)。
hello_world当使用参数执行我的方法时1,在执行之前我有以下堆栈invokedynamic 2:
----TOP---
0x00000001
--BOTTOM--
Run Code Online (Sandbox Code Playgroud)
我的问题是:我该如何使用invokedynamic?
我无法解析该方法makeConcatWithConstants,因为 InvokeDynamic-Constant 没有给我任何makeConcatWithConstants可能位于何处的提示(请参阅文档)。
堆栈也不包含对堆的引用,指示该方法makeConcatWithConstants可以与哪个实例类型关联。
我通读了文档invokedynamic,但我不明白它(也许我被 .NET-Framework 严重“损坏”了)。
有人能给我举一些关于执行这三个指令时 JVM 内部发生的事情的示例吗?(被调用者invokedynamic期望什么等)?
我已经invokestatic在我的 JVM 中实现了......但我目前无法理解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!
Run Code Online (Sandbox Code Playgroud)
您可以在其中看到此特定调用站点的引导方法位于StringConcatFactory
它们Method arguments是常量参数的集合。
Lookup、String和的主要论点MethodType分别是;与调用点具有相同权限、某些名称和调用点类型的查找对象。其中第一个需要由VM在运行时提供,后两个由invokedynamic常量池条目以名称和类型的形式提供:
#2 = InvokeDynamic #0:#17 // #0:makeConcatWithConstants:(I)Ljava/lang/String;
Run Code Online (Sandbox Code Playgroud)
因此,要实现此字节码,您必须有一些机制来创建查找对象,然后能够调用引导方法。之后,您可以调用dynamicInvoker()返回的Callsite对象,该对象会为您提供一个对象,MethodHandle然后您应该缓存该特定的调用站点,然后(最后)调用。
如果您想了解 OpenJDK 中是如何实现的,您可以在这里找到实现:http://hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/interpreter/bytecodeInterpreter.cpp #l2446
我猜想这在项目的早期阶段可能太棘手了,所以现在用 编译你的程序可能会更容易-XDstringConcat=inline,因为它使用了遗留的StringBuilder串联,这应该更容易实现。
| 归档时间: |
|
| 查看次数: |
1984 次 |
| 最近记录: |