Javac 实现:方法调用产生哪些 jvm 指令?
Javac Implementation: What jvm instructions does a method call produce?
假设我在 java 中有一个方法调用站点。什么是等效的 jvm 字节码(除了被翻译成 invokevirtual/static e.t.c 的调用)?我对将接收器加载到堆栈上的命令更感兴趣。
-显然一个命令就是一个加载。
-另一个可能是另一个调用returns 堆栈上的引用对象
-三、新指令。 (例如 new A().foo()。它被复制了。但是复制的被构造函数消耗了)
-四,也许(??) 对。 (当有 a.foo(); a.bar(); 编译器是否有机会生成 aload 然后 dup 而不是 aload aload?)
我最大的问题是 rest dup 命令。因为他们有点洗牌。 javac 什么时候生产它们?编译调用站点时是否使用它们?
我曾尝试查找文档,但没有成功。然后找到了源代码,但要花几天时间才能深入研究。我相信 Code.java and Gen.java 文件负责 translation/compilation 过程。
javac 可以使用几乎任何 产生引用的字节码指令来加载接收器。
- aload, invokeX, new + dup
您已经提到的那些。
getfield, getstatic
field.method();
aaload
arr[index].method();
anewarray
(new Object[0]).hashCode();
multianewarray
(new byte[5][10]).getClass();
checkcast
((List) obj).size();
ldc
MyClass.class.getName();
aconst_null
((Object) null).getClass();
dup
IntSupplier s = field::hashCode;
此处 dup
+ invokevirtual
用于发出棘手的空检查:
getstatic #2 // Field field:Ljava/lang/String;
dup
invokevirtual #3 // Method java/lang/Object.getClass:()Ljava/lang/Class;
pop
invokedynamic #4, 0 // InvokeDynamic #0:getAsInt
假设我在 java 中有一个方法调用站点。什么是等效的 jvm 字节码(除了被翻译成 invokevirtual/static e.t.c 的调用)?我对将接收器加载到堆栈上的命令更感兴趣。
-显然一个命令就是一个加载。
-另一个可能是另一个调用returns 堆栈上的引用对象
-三、新指令。 (例如 new A().foo()。它被复制了。但是复制的被构造函数消耗了)
-四,也许(??) 对。 (当有 a.foo(); a.bar(); 编译器是否有机会生成 aload 然后 dup 而不是 aload aload?)
我最大的问题是 rest dup 命令。因为他们有点洗牌。 javac 什么时候生产它们?编译调用站点时是否使用它们?
我曾尝试查找文档,但没有成功。然后找到了源代码,但要花几天时间才能深入研究。我相信 Code.java and Gen.java 文件负责 translation/compilation 过程。
javac 可以使用几乎任何 产生引用的字节码指令来加载接收器。
- aload, invokeX, new + dup
您已经提到的那些。 getfield, getstatic
field.method();
aaload
arr[index].method();
anewarray
(new Object[0]).hashCode();
multianewarray
(new byte[5][10]).getClass();
checkcast
((List) obj).size();
ldc
MyClass.class.getName();
aconst_null
((Object) null).getClass();
dup
IntSupplier s = field::hashCode;
此处
dup
+invokevirtual
用于发出棘手的空检查:getstatic #2 // Field field:Ljava/lang/String; dup invokevirtual #3 // Method java/lang/Object.getClass:()Ljava/lang/Class; pop invokedynamic #4, 0 // InvokeDynamic #0:getAsInt