问题标签 [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.
spring - spring 支持为 groovy-backed bean 调用动态吗?
是否可以配置使用lang命名空间或手动使用GroovyScriptFactory声明的 Groovy bean ,使其使用调用动态支持?
我没有找到任何关于此案的可靠文件。
而且,groovy-all:indy maven 工件提供的 GroovyClassLoader 是否使用此功能,还是只能与 groovy 编译器一起使用?
performance - 优化 Groovy 性能
我正在研究 groovy 代码性能优化。我使用 jvisualvm 连接到正在运行的应用程序并收集 CPU 样本。样本说org.codehaus.groovy.reflection.CachedMethod.inkove占用的 CPU 时间最多。我在示例中没有看到任何其他应用方法。
深入研究 CachedMethod.invoke并了解哪些代码行真正会导致性能下降的正确方法是什么?
谢谢。
UPD:我确实使用Indy,它对我没有帮助。
我没有尝试引入@CompileStatic,因为我想在将groovy 重写为java 之前找到我的瓶颈。
我的问题有点类似于这个线程:调用站点缓存比调用动态更快?
我有一个动态编写 groovy 脚本的代码。脚本模板看起来是这样的:
其中%s替换为
从数据库中获取了一组(总共 20 个)替换项。代码从 DB 获取替换,创建 GroovyScript 并评估它。我想瓶颈在于脚本执行。修复它的正确方法是什么?
java - MethodHandles 还是 LambdaMetafactory?
在我的工作中,我们有一个用于指定数学公式的 DSL,我们后来将其应用于很多点(以百万计)。
截至今天,我们构建了公式的 AST,并访问每个节点以生成我们所谓的“评估器”。然后我们将公式的参数传递给该评估器,并针对每个点进行计算。
例如,我们有这个公式:x * (3 + y)
我们的评估器将为每个步骤发出“评估”对象。
这种方法易于编程,但效率不高。
所以我开始研究方法句柄来建立一个“组合”的方法句柄来加快速度。
沿着这个:我有我的“算术”课:
在构建我的 AST 时,我使用 MethodHandles.lookup() 直接获取这些句柄并组合它们。沿着这些思路,但在一棵树上:
可悲的是,我对结果感到非常失望。例如,方法句柄的实际构造非常长(由于调用 MethodHandles::insertArguments 和其他此类组合函数),并且为评估增加的加速仅在超过 600k 次迭代后才开始产生影响。
在 1000 万次迭代时,方法句柄开始真正发光,但数百万次迭代还不是(还?)一个典型的用例。我们更多的是在 10k-1M 左右,结果好坏参半。
此外,实际计算速度加快了,但速度不快(约 2-10 倍)。我期待这东西跑得快一点..
所以无论如何,我再次开始搜索 StackOverflow,并看到了像这样的 LambdaMetafactory 线程:https ://stackoverflow.com/a/19563000/389405
我很想开始尝试这个。但在此之前,我希望您能就一些问题提供意见:
我需要能够编写所有这些 lambda。MethodHandles 提供了很多(不可否认的缓慢)方法来做到这一点,但我觉得 lambdas 有一个更严格的“接口”,我还不能解决如何做到这一点。你知不知道怎么?
lambdas 和方法句柄是相互关联的,我不确定我是否会获得显着的加速。我看到了简单 lambda 的这些结果:
direct: 0,02s, lambda: 0,02s, mh: 0,35s, reflection: 0,40
但是组合 lambda 呢?
多谢你们!
java - 使用 invokedynamic 时的泛型信息
我正在创建一个 java 框架来在 Invoke dynamic 的帮助下转换 bean。我用 ASM 创建了转换类。为了生成如下所示的转换:
我用 ASM 编写了以下字节码:
然后 convert 方法搜索可以处理给定类型的转换器。这看起来像:
这适用于说字符串到整数的转换。但不适用于泛型。sourceType 只是Ljava/util/List;
而不是完整的Ljava/util/List<Ljava/lang/String;>;
如何在此引导方法中获得完整类型?
java - Java字节码、Java供应商和invokedynamic参数
我有这个类,我编译它。
然后,试图查看它的字节码,我得到以下public static void main
函数的开头:
在这里,我们可以看到 invokedynamic 调用,如果我理解正确的话,它会创建 Supplier 接口的匿名实例。传递给invokedynamic 的是两个参数,一个是#3。第二个参数是 0。所以,我的第一个问题是:这里的 0 代表什么?
在常量池中,#3 代表#3 = InvokeDynamic #0:#27 // #0:get:()Ljava/util/function/Supplier;
. 常量池中有对#27 的引用,但没有对#0 的引用。我的第二个问题是:#0 在这里代表什么?
java - 池捕获 lambda
我认为为了捕获 lambda,需要分配一个对象(无论是它Object[]
还是某种abc$Lambda$xyz
类型)。无论如何都可以自定义此过程吗?假设我有这个代码:
而且我不想分配对象捕获x
,而是从池中获取它并填写值;我也知道在某些时候我可以将对象返回到池中。
我可以写
并且我可以为不同的参数类型提供专门的版本(因为 usingObject...
会进行分配(好吧,分配可能会被转义分析消除......)但这会使代码变得非常不可读。因此我正在寻找一种更像方面的方式。
这样的事情可能吗?
编辑:为了使池的功能更加明显,get
可以实现为
对于我想使用的所有可能类型的 lambda,我需要这种具有特定签名的持有者。
也许我通过提供函数使示例变得有点复杂 - 但我想捕捉这样一个事实,即在Supplier.get()
调用时可能会对捕获的参数应用额外的计算。
请忽略 int 被装箱的事实,它可以产生分配。
java - ASM 不能将“Type.INT_TYPE”作为常量引导方法参数传递
考虑以下旨在invokedynamic
使用 ASM 生成指令的代码:
使用 ASMifier 反编译生成的类时,相关行变为
如您所见,Type.INT_TYPE
已变成对名为 的引用类型的字面引用I
。由于这不存在,JVM 在运行时抱怨java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: I
.
相反,我想做的是将int.class
(Class
原始类型的实例int
,或Integer.TYPE
常量的值)传递给我的bootstrap
方法作为someClass
. 但是,ASM 似乎没有正确理解或支持这一点。
这是否可以被视为 ASM 错误,是否有解决方法?
scala - 为什么 Java8 和 Scala2.12 lambda 缓存有区别?
Java 代码
Scala 代码(版本 2.12.0)
结果
java - java.lang.NoClassDefFoundError:jdk.nashorn.internal.scripts.JO28P0
我完成了一个 Java 库,并用它来替换java.lang.invoke
包(即,在正常 JVM 库之前将其添加到引导类加载器)。在包中,它为方法句柄动态生成字节码。如果您有任何关于这门课的信息,谢谢!
目前,这个包在带有测试用例的 JRuby 上运行良好,但是当我尝试用 Nashorn(JavaScript 语言的 Java 版本)测试它时它失败了。错误信息是:
除了例外,我在 nashorn 包中找不到任何类 JO28P0。我无法通过谷歌获得该课程的任何信息。
这里的 JS 来自 octane 基准测试,我在其中评论了除前两种情况之外的所有测试:
启动该案例的主要 Java 代码是:
一个 VM 参数是-Djit_bytecode=true
. 如果这个论点是真的,那么将去我的图书馆。否则,我的库将不会生效。
如果jit_bytecode
为假,则异常消失。
更新:
我的代码发出动态字节码,其中包含 symbol JO28P0
。当我尝试使用UNSAFE.defineAnonymousClass()
. 那么如何使用 Structure ClassLoaderUnsafe.defineAnonymousClass
才能成功呢?
java - ScriptEngineManager.getEngineByName("nashorn") 由于 java.lang.invoke.WrongMethodTypeException 而失败
我无法在 Java 8 (IBM J9JVM) 中创建ScriptEngine
。nashorn
在下面的代码中,引擎是null
.
这个失败是由我的库引入的,它为java.lang.invoke
包中的 MethodHandle 执行字节码生成。我的图书馆的变化是:
- 更改仅适用于标准
java.lang.invoke
包。nashorn 没有任何变化。 - 当 nashorn 即将使用 设置调用站点的目标时
Methodhandle target
,我的库将转换target
为另一个方法句柄b
,如果从target
创建GuardWithTestHandle
并将调用站点的目标设置为b
。两个“目标and
b”具有相同的方法类型。
我的上一个版本库于 2016 年 10 月完成,对 Nashorn 来说还可以。但是我构建的新版本WrongMethodTypeException
在执行时有getEngineByName
. 此异常在内部处理getEngineByName
并返回 null。
我得到的 nashorn 源代码与 JVM 中的 nashorn.jar 不一致。在调试过程中,我发现异常来自:
全局 = createNashornGlobal();
里面NashornScriptEngine.<init>
。UserAccessorProperty
深入消化后,在(line318)处进行MethodHandle调用时抛出异常
在第 318 行,invoker
isMutableCallSiteDynamicInvokerHandle
及其方法类型为(Object,Object)Object
。func
和都在这里self
声明为Object
对象,参数类型和返回值完全匹配。
我无法理解此异常,也不知道此问题的后续步骤。谢谢,如果你能在这里为这个问题提供一些想法和建议吗?或一些选项/配置..