gpt4 book ai didi

java - jvm dup 指令的用例

转载 作者:行者123 更新时间:2023-12-02 10:53:22 26 4
gpt4 key购买 nike

Java字节码指令集提供various forms of dup instruction 。我无法理解这些指令和 swap 指令的用途。哪些 Java 代码在编译时会使用这些指令生成字节码?

最佳答案

dup 的变体可以出现在普通 Java 代码中。

例如如 this answer 中所述,对象实例化通常使用 dup,因为 new Object() 被编译为

new #n              // n referencing Class java.lang.Object in the pool
dup
invokespecial #m // m referencing Method java.lang.Object.<init>()V

此外,intArray[expression]++ 被编译为

… (code pushing the results of intArray and expression)
dup2
iaload
iconst_1
iadd
iastore

而且,有点花哨

public static long example3(Long[] array, int i, long l) {
return array[i]=l;
}

编译为

   0: aload_0
1: iload_1
2: lload_2
3: invokestatic #3 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
6: dup_x2
7: aastore
8: invokevirtual #4 // Method java/lang/Long.longValue:()J
11: lreturn

将数组类型更改为 long[] 会生成 dup2_x2

的示例

this Q&A 中所述,javac 永远不会使用 swapnop(在当前实现中)。但仅仅因为 javac 不使用特定指令,您就不能假设没有编译器使用它。

例如还有其他 Java 编译器,例如 ECJ,但也可能存在由其他编程语言创建的类文件,或者已经是检测工具的结果,当您想要在运行时检测代码时,这些文件就变得相关。并且 javac 的 future 版本也可以使用以前没有使用过的指令,就像 Java 8 之前一样,Java 代码不使用 invokedynamic

This discussion指向一个适合交换的场景。当使用 try-with-resource 时,将会生成代码,在已经捕获到异常的情况下处理捕获到的异常。当前 javac 将其编译(基本上)为

astore        n
aload o
aload n
invokevirtual #x // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V

其中 o 是保存已捕获异常的旧变量,n 将是一个全新的变量,将其编译为

aload         o
swap
invokevirtual #x // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V

相反。所以这些指令并不是永远不需要的奇异结构。当特定的代码生成器不使用它们时,这只是一个实现细节。

说到 Instrumentation,同样重要的是要记住,ClassFileTransformer 不能保证接收与编译器生成的完全相同的字节码。它可能是等效的字节代码。

所以底线是,如果你想实现一个ClassFileTransformer,你应该准备好处理每个合法的字节码。

关于java - jvm dup 指令的用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54781284/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com