2

背景

我目前正在用 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

在常量池中查看 index 处的常量时2,我​​看到一个 InvokeDynamic-Constant 条目,其中包含以下数据:

makeConcatWithConstants : (I)Ljava/lang/String;

我想这是有道理的(我更像是 .NET 用户而不是 JAVA 用户)。

hello_world使用参数执行我的方法时1,在执行之前我有以下堆栈invokedynamic 2

----TOP---
0x00000001
--BOTTOM--

问题

我的问题是:我该如何使用invokedynamic
我无法解析该方法makeConcatWithConstants,因为 InvokeDynamic-Constant 没有给我任何提示,makeConcatWithConstants可能位于何处(请参阅文档)。
堆栈也不包含对堆的引用,指示该方法makeConcatWithConstants可以与哪个实例类型相关联。

我通读invokedynamic文档,但我不明白(也许我被 .NET-Framework 严重“损坏”了)。

有人可以给我举一些例子,说明在执行这三个指令时 JVM 引擎盖下发生了什么?(被调用者invokedynamic期望什么等)?

我已经invokestatic在我的 JVM 中实现了……但我目前无法理解invokedynamic

4

1 回答 1

3

的想法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

是一Method arguments组常量参数。

和的主要参数Lookup分别是;具有与调用站点相同的权限、一些名称和调用站点的类型的查找对象。其中第一个需要由VM在运行时提供,后两个由invokedynamic常量池条目以名称和类型的形式提供:StringMethodType

#2 = InvokeDynamic      #0:#17         // #0:makeConcatWithConstants:(I)Ljava/lang/String;

所以要实现这个字节码,你必须有一些机制来创建查找对象,然后能够调用引导方法。之后,您可以调用dynamicInvoker()返回的Callsite对象,这为您提供了一个MethodHandle您应该为这个特定的调用站点缓存然后(最终)调用的对象。

如果你想看看 OpenJDK 是如何实现的,你可以在这里找到实现:http: //hg.openjdk.java.net/jdk/jdk/file/tip/src/hotspot/share/interpreter/bytecodeInterpreter.cpp #l2446

我猜这在项目的早期阶段可能太棘手了,所以现在用 编译你的程序可能更容易-XDstringConcat=inline,因为它使用了遗留StringBuilder连接,这应该更容易实现。

于 2018-11-04T11:08:01.620 回答