首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用"invokedynamic“-引擎盖下面发生了什么?

使用"invokedynamic“-引擎盖下面发生了什么?
EN

Stack Overflow用户
提问于 2018-11-04 10:18:54
回答 1查看 1.5K关注 0票数 2

背景

我目前正在C#中编写一个JVM,纯粹是为了学术目的(也许将来还会构建一个混合的.NET和Java/Scala应用程序)。

上下文

我编写了简单的类:

代码语言:javascript
复制
public class test
{
    public static String hello_world(int i)
    {
        return "Hello " + i + " World!";
    }
}

并将其编译成test.class。当我用我的反编译器(我作为JVM的一部分编写)反编译它时,我看到了关于这个方法的以下说明:

代码语言:javascript
复制
iload_0
invokedynamic 2
areturn

当在常量池中查看索引2上的常量时,我看到一个InvokeDynamic常量条目,其中包含以下数据:

代码语言:javascript
复制
makeConcatWithConstants : (I)Ljava/lang/String;

这是有意义的,我想(我更多的是一个.NET用户而不是一个JAVA用户)。

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

代码语言:javascript
复制
----TOP---
0x00000001
--BOTTOM--

问题

我的问题是:如何使用invokedynamic**?**

我无法解析方法makeConcatWithConstants,因为InvokeDynamic常量没有给我任何提示,makeConcatWithConstants可能位于哪里(见文件)。

堆栈也不包含对堆的引用,指示可以与makeConcatWithConstants关联的方法的实例类型。

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

有人能给我举个例子,说明在执行这三个指令时JVM的引擎盖下发生了什么吗?( invokedynamic的要求是什么?)

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-04 11:08:01

invokedynamic的思想是:当第一次遇到这个字节码时,调用一个引导方法,它创建一个链接到需要调用的实际方法的Callsite对象。

在实践中,这通常意味着动态地为调用创建实现。

如果您使用javap -v test查看您的程序,您将在底部看到一个BootstrapMethods属性:

代码语言:javascript
复制
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是一组常量参数。

LookupStringMethodType的前导参数分别是:具有与回调站点相同的优先级的查找对象、名称和回调站点的类型。其中的第一个需要在运行时由VM提供,而后面的2个则由以名称和类型的形式提供:

代码语言:javascript
复制
#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连接,这应该更容易实现。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53139737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档