- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请提供一段用一些众所周知的动态语言(例如 JavaScript)编写的代码,以及该代码在使用 invokedynamic 的 Java 字节码中的样子,并解释为什么使用 invokedynamic 是向前迈出的一步。
我已经在 Google 上搜索并阅读了很多关于不再是新的 invokedynamic 指令的信息,互联网上的每个人都同意它有助于加速 JVM 上的动态语言。 Thanks to stackoverflow我设法让我自己的字节码指令与 Sable/Jasmin 一起运行。
我知道 invokedynamic 对惰性常量很有用,我也认为我理解了 the OpenJDK takes advantage of invokedynamic for lambdas .
Oracle 有 a small example ,但据我所知,在这种情况下,invokedynamic 的使用违背了目的,因为“加法器”的示例可能更简单、更快,并且与以下字节码表达的效果大致相同:
aload whereeverAIs
checkcast java/lang/Integer
aload whereeverBIs
checkcast java/lang/Integer
invokestatic IntegerOps/adder(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;
因为出于某种原因,Oracle 的引导方法知道两个参数都是整数。他们甚至“承认”:
[..]it assumes that the arguments [..] will be Integer objects. A bootstrap method requires additional code to properly link invokedynamic [..] if the parameters of the bootstrap method (in this example, callerClass, dynMethodName, and dynMethodType) vary.
嗯,是的,如果没有那个有趣的“附加代码”,那么在这里使用 invokedynamic 是没有意义的,是吗?
因此,在那之后以及一些其他的 Javadoc 和博客条目之后,我认为我已经很好地掌握了如何在 invokestatic/invokevirtual/invokevirtual 或 getfield 也能正常工作时使用 invokedynamic 作为糟糕的替代品。
现在我很好奇如何将 invokedynamic 指令实际应用到现实世界的用例中,以便它实际上是对“传统”调用的一些改进(除了惰性常量,我得到了那些......)。
最佳答案
实际上,如果您广义地理解“延迟创建”一词,那么延迟操作就是 invokedynamic
的主要优势。例如,Java 8 的 lambda 创建特性是一种惰性创建,其中包括可能包含最终将由 invokedynamic
指令调用的代码的实际类在执行该指令。
这可以转换到所有类型的脚本语言,以不同于 Java 字节码的形式提供代码(甚至可能在源代码中)。在这里,代码可以在第一次调用方法之前编译并在之后保持链接。但是,如果脚本语言支持重新定义方法,它甚至可能会变得未链接。这使用了 invokedynamic
的第二个重要特性,允许可变的 CallSite
之后可以更改,同时在不重新定义的情况下频繁调用时支持最大性能。
这种事后更改 invokedynamic
目标的可能性允许另一个选项,在第一次调用时链接到解释执行,计算执行次数并仅在超过阈值后编译代码(并重新链接到然后编译代码)。
关于基于运行时实例的动态方法分派(dispatch),很明显invokedynamic
不能省略分派(dispatch)算法。但是,如果您在运行时检测到特定调用站点将始终调用相同具体类型的方法,您可以将 CallSite
重新链接到优化代码,该代码将简短检查目标是否符合预期然后键入并执行优化操作,但仅在测试失败时才分支到执行完整动态调度的通用代码。如果它检测到快速路径检查失败了一定次数,该实现甚至可能取消优化这样的调用站点。
这类似于 invokevirtual
和 invokeinterface
如何在 JVM 内部进行优化.因此,使用 invokedynamic
您可以将相同的技术用于任意查找算法。
但如果您想要一个完全不同的用例,您可以使用 invokedynamic
来实现标准访问修饰符规则不支持的 friend
语义。假设你有一个类 A
和 B
意味着有这样的 friend
关系,因为 A
是允许的调用 B
的 private
方法。然后,所有这些调用都可以编码为具有所需名称和签名的 invokedynamic
指令,并指向 B
中的 public
引导方法,可能看起来像这个:
public static CallSite bootStrap(Lookup l, String name, MethodType type)
throws NoSuchMethodException, IllegalAccessException {
if(l.lookupClass()!=A.class || (l.lookupModes()&0xf)!=0xf)
throw new SecurityException("unprivileged caller");
l=MethodHandles.lookup();
return new ConstantCallSite(l.findStatic(B.class, name, type));
}
它首先验证提供的 Lookup
对象是否具有对 A
的完全访问权限,因为只有 A
能够构造这样的对象。因此,错误来电者的偷偷摸摸的尝试在这个地方被整理出来。然后它使用对 B
具有完全访问权限的 Lookup
对象来完成链接。所以,这些 invokedynamic
指令中的每一个在第一次调用后都永久链接到 B
的匹配 private
方法,以与普通相同的速度运行之后调用。
关于dynamic - invokedynamic 什么时候真正有用(除了惰性常量)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24171950/
Java 8 引入了对一等函数的支持,允许将函数分配给变量。在这种情况下,变量必须是函数类型,它由函数式接口(interface)(只有一个抽象方法的接口(interface))定义。 因此,考虑一个
最近,我正在阅读有关 Java 7 功能的内容,invokedynamic 是最令人期待的功能之一。大多数博客/文章都从 JVM 实现的角度提供了优点,特别是对于动态类型语言。从应用程序开发人员的角度
为了支持动态类型和方法分派(dispatch),我的编程语言引入了一种称为dynamic 的类型。当在类型为 dynamic 的被调用者上调用方法时,编译器首先将被调用者和所有参数压入堆栈,然后生成一
我正在尝试在 JVM7 中使用 invokedynamic 实现“duck typing”。我创建了两个不同的类,它们都有返回 String 的方法 greet()。我随机选择其中之一,将实例存储在堆
是否可以使用 InvokeDynamic for Grails? 如果是,哪些版本的 Grails、Java 等兼容? 设置过程是怎样的? 如果不可能,什么时候可以将 InvokeDynamic 支持
TL;DR 请提供一段用一些众所周知的动态语言(例如 JavaScript)编写的代码,以及该代码在使用 invokedynamic 的 Java 字节码中的样子,并解释为什么使用 invokedyn
背景 我目前正在用 C# 编写 JVM,纯粹出于学术目的(也许将来会构建混合的 .NET 和 Java/Scala 应用程序)。 上下文 我编写了简单的JAVA类: public class test
我想知道是否可以使用 Java7 的新 invokedynamic 字节码指令来实现 multiple dispatch对于 Java 语言。 java.lang.invoke 下的新 API 是否有
在对 invokeDynamic 进行了大量阅读之后,我仍然有点困惑。一个重复的主题似乎是 Clojure 并不真正需要它,或者至少比 JVM 上的其他动态语言实现(Jruby、JPython)更少需
我渴望在 Java 之上开始使用动态语言。 这成为标准 JDK 的一部分需要多长时间? 最佳答案 Java 7 发布时。目前,最好的猜测是 2010 年底,但可能会发生变化。 Keep an eye
$ scala -Xexperimental Welcome to Scala version 2.9.0.1 (OpenJDK Server VM, Java 1.6.0_22). Type in
想一想动态的、预测的方面语言。可以调用方面(即方法)代替或之前和之后原始方法。这些方面在运行时打开和关闭。甚至可能是,多个方面想要更改相同方法,这将导致这些方面组合成一个方法调用链。 原始方法由加载时
我正在通过 ASM 使用 Java 字节码并试图让一个简单的 invokedynamic 示例正常运行。我觉得好像我从根本上误解了 invokedynamic 应该如何工作。到目前为止,这是我尝试过的
invokedynamic 指令用于帮助虚拟机在运行时确定方法引用,而不是在编译时对其进行硬连接。 这对于动态语言很有用,在动态语言中,直到运行时才知道确切的方法和参数类型。但 Java lambda
是否有估计表明 JSR-292 将对 Groovy 性能产生多大影响? 最佳答案 invokedynamic 确实是一个复杂的故事,因为性能特征在 JDK7 中一直在变化。在将 Groovy 移植到
我有这个类,我编译它。 package org.test; import java.util.function.Supplier; public class Test { static Str
今天下载了studio 3.0 beta 2.0版本,之后尝试在里面打开一个已有的项目,遇到了一些困难,大部分问题我可以借助Google和Stack Overflow解决,但是这个我不行。 Error
我想看看如何使用与 invokevirtual 相同的调度逻辑进行 invokedynamic 调用。 我问这个问题是因为目前在线的使用 ASM 生成动态方法调用的示例太琐碎而无法概括,我认为这种情况
我的 Android 应用程序像这样使用 Java 8 lambda: myView.setOnClickListener(view -> someMethod()); 在构建应用程序或运行单元测试时
我在 Android Studio 3.0 中遇到了这个错误(在 2.3 中出现了另一个错误)。几个小时以来,我一直在尝试修复删除一些依赖项,但没有任何效果。所以现在我不想要我还能尝试什么。
我是一名优秀的程序员,十分优秀!