问题标签 [invokedynamic]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
396 浏览

java - 调用动态的 Groovy 性能问题?

我正在努力确定是什么导致了一个中等大小的 Groovy 应用程序在生产中运行缓慢。当获取正在运行的应用程序的线程转储时,我看到的奇怪的事情是很多线程都有这样的堆栈跟踪:

我在网上看到有人提到该setCallSiteTargetNormal方法是相当重量级的,并且在调用它时会阻塞所有 JVM 线程。我们使用 Groovy 的调用动态支持,我想知道我们是否遇到了 Groovy 中的某种错误,导致该方法被过度调用。

我已经检查过的明显性能问题:

  • 内存使用没问题
  • GC 开销是正常的
  • 服务器上的 CPU 使用率看起来还不错
  • 外部数据库和网络服务调用都正常

关于 CPU 使用率的一个注意事项是,该应用程序的行为就像它需要 CPU 一样,但它只使用了 4 CPU 机器的总 CPU 的大约 1/4。它的行为就像一个线程应该 100% 与 CPU 挂钩,但我根本没有看到这一点。然而,我在网上找到的一些信息表明setCallSiTeTargetNormal方法调用完全阻塞了 JVM 上的所有线程。

0 投票
1 回答
360 浏览

java - 使用 MethodHandles 和 invokedynamic 链接方法调用

想一想动态的、谓词方面的语言。可以调用方面(即方法)来代替或在原始方法之前之后调用。这些方面在运行时打开和关闭。甚至可能是多个方面想要更改同一个方法,这将导致这些方面组合成一个方法调用链。

原始方法由加载时编译器(JPLIS 和 ASM)更改。我得到了一些看起来像这样的字节码:

有趣的部分是引导方法应该以特定方式工作:

  • 返回具有兼容参数列表的方法串联。这些MethodHandles 绑定到调用它们的不同类型的不同实例。
  • 结果可能MethodHandle只是绑定到其他实例,而不是绑定到调用引导方法的实例。因此,应该省略使用this调用生成的调用站点(下面替代方案中的第一个分支)。

也有可能直接调用原来的方法,完全没问题。

在此处输入图像描述

在我看来,MethodHandles 是实现这一目标的正确方法。我的问题是,如果一切都可以在单个引导方法中实现,那么我可以使用从绑定到调用站点的引导方法返回的方法句柄链来链接方法调用,如序列图中所示。

0 投票
3 回答
11776 浏览

java - Java 9 中如何实现字符串连接?

JEP 280 中所写: Indify String Concatenation

更改String生成的静态连接字节码序列javac以使用invokedynamic对 JDK 库函数的调用。这将使未来的String连接优化成为可能,而无需进一步更改javac.

在这里我想了解invokedynamic调用的用途是什么以及字节码连接有什么不同invokedynamic

0 投票
1 回答
2468 浏览

java - 调用方法时Java中的调用站点是什么?

我试图了解什么是 JVM 中的调用站点。引用自https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.6

调用站点说明符解析的结果是一个元组,包括:

• 对 的实例的引用java.lang.invoke.MethodHandle

• 对 的实例的引用java.lang.invoke.MethodType

Class• 对、java.lang.invoke.MethodHandlejava.lang.invoke.MethodType和的实例的引用String

我们还有所谓的调用站点对象https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic

bootstrap 方法返回的结果必须是对类为 的对象java.lang.invoke.CallSite或其子类 的引用java.lang.invoke.CallSite。此对象称为调用站点对象

调用站点对象的概念很明确。这只是CallSite. 但是调用站点说明符呢?那是一个Java对象吗?那是String字面意思吗?

0 投票
0 回答
776 浏览

android - android sdk <26(奥利奥)上的`invokedynamic`?

有没有办法invokedynamic在比 sdk 级别 26(即 Oreo、Android 8)的旧版本上使用?即只需安装较新的VM (ART) 版本。

因为它是一个 VM 功能,它不会独立于所有非 VM sdk 级别 26 功能,并且可以在任何版本的 android 上运行吗?

PS 这是为了让kotlin 编译器在 android 上运行

0 投票
1 回答
729 浏览

java - 如何使用 LambdaMetaFactory 调用构造函数?

我想尝试避免反射调用构造函数,并尝试遵循本文中采用的 LamdaMetaFactory 方法 - Java 反射的更快替代方案

我要构建的课程如下所示:

使用LambaMetaFactory我正在尝试构造一个BiFunction<BrokerPool, Configuration, DBBroker>来替换对构造函数的直接调用。

到目前为止,我的代码如下所示:

不幸的是,这会返回错误-

AbstractMethodError: 方法 org/exist/storage/BrokerFactory$$Lambda$55.apply(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; 是抽象的。

我已经尝试修改传递给的各种类型,LambdaMetafactory.metafactory但我似乎不能完全正确地做到这一点,而且 Javadoc 肯定不容易理解。

有人可以建议吗?

0 投票
1 回答
112 浏览

java - 通过公共查找检索数组克隆方法句柄

最近尝试通过库来访问clone数组类型的方法。java.lang.invoke这被证明是不成功的。示例中的克隆方法是这样的:

我希望MethodHandlea.clone()通话创建一个。这样生成的代码类似于:

我为所有其他方法调用设置了这个系统。但是,仅使用这种方法,系统就会失败。

这个问题与java.lang.invoke图书馆有关,而不是java.lang.reflect图书馆。

问题描述

引入了以下示例代码来显示此行为。

样本输出:

查找:主要

mh:方法句柄(主)对象


输出是有道理的。范围内的调用者Main只能看到的超类clone中的方法MainObject。即使int[]用作参考类,此方法也是不可见的。这成为一个问题,因为如果使用此调用站点,JVM 会尝试强制转换int[]Main.

通过将引用类型引入为int[],人们会期望clonetype 中的方法int[]是可公开访问的。因此,当文档建议时:

方法句柄的类型将是方法的类型,并带有接收者类型(通常是 refc)。1

的类型mh将是(int[])Object


尝试的解决方案:

由于查找caller通过遮蔽正确的clone方法进行干扰,因此尝试使用公共查找:

然而,这失败了。Object#clone()对签名的简单检查说明了原因:

方法是protected。这不适用于数组类型,因为实现使该方法公开可用。

这方面的一个例子是尝试访问该Object#equals方法。这与三个单独的参考类一起显示:

查找:java.lang.Object/public

mh:方法句柄(对象,对象)布尔

然后Main.class用作参考类:

查找:java.lang.Object/public

mh:方法句柄(主要,对象)布尔

然后int[].class用作参考类:

查找:主要

mh: MethodHandle(int[],Object)boolean

这是预期的行为,显然可以流畅地工作。在第一种情况下,引用类是Object并且它返回Object#equals方法句柄。第二个是引用类Main,它返回Main#equals方法句柄。最后,引用类是int[].class并且它返回了int[]#equals方法句柄。

但是,该方法不能保持这种奇偶性int[]#clone。由于该clone方法是受保护的,但对于数组是公共的,因此无法找到它。对我来说,这似乎是一个错误。数组clone方法应该通过publicLookup. 返回的方法句柄类型可能是:MethodHandle(Object)Object

一旦检索到,MethodHandle#asType然后可以用于更正类型。在这种情况下,它将被转换为MethodHandle(int[])Object.

如果没有Object#clone公开可用的方法,至少对于数组类型,这似乎是不可能的。

此外,这似乎是唯一可能发生这种情况的方法,因为数组类型仅扩展/实现 3 个类ObjectCloneableSerializable. 唯一的其他方法Object#finalize也是受保护的;但是,数组类型不会公开此方法。因此clone,这是唯一失败的方法。


tl;博士:

数组clone方法,例如Object[]#clone(),不能通过公共查找公开访问。这是因为Object#cloneprotected;但是,数组类型使此方法公开可用。clone由于此可见性问题,尝试通过引用类访问数组失败。因此,MethodHandle无法为此方法生成 a。但是,在公共方法上尝试相同的技术,例如Object#equals对数组类型效果很好。


我宁愿避免反射访问,因为方法可以通过简单地更改查找的信任级别来检索它。

有没有办法MethodHandle为数组clone方法生成一个?


注意:我确实了解 的正确用法,java.lang.invoke并且我不打算将其用作java.lang.reflect.

0 投票
1 回答
324 浏览

groovy - 为什么 Invokedynamic 不是 Groovy 中的默认设置?

Groovy--indy在 2012 年的 2.0 版中添加了该选项。当时它不是默认设置,因为invoke dynamic需要 Java 7,而且当时很多人使用 Java 6。

现在即使是即将推出的 Groovy 3.0 仍然需要该--indy选项才能强制它使用invoke dynamic. 尽管 Groovy 3.0 需要 Java 8 或更高版本,但还是会这样。

仍然具有默认的非 indy 编译和默认的运行时库是非 indy 是否有任何技术优势?我会认为现在甚至不需要非独立选项。

0 投票
1 回答
647 浏览

java - 如何使用 ASM 生成模拟 invokevirtual 的 invokedynamic 调用

我想看看如何invokedynamic使用与invokevirtual.

我问这个问题是因为目前在线使用 ASM 生成动态方法调用的示例太琐碎而无法概括,我认为这种情况对于任何想要实现自己的调度逻辑的人来说都是一个很好的起点。

显然,我知道在实践中仅仅用一个替换invokevirtual调用invokedynamic将是一件毫无意义的事情。

要清楚,我想替换它:

有了这个:

// 引导方法

0 投票
1 回答
1104 浏览

java - 使用“invokedynamic” - 引擎盖下发生了什么?

背景

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

语境

我编写了简单的JAVA类:

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

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

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

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

问题

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

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

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

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