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