Javac实现:方法调用产生哪些jvm指令?

时间:2018-12-21 10:28:26

标签: java jvm javac method-call

假设我在Java中有一个方法调用站点。等效的jvm字节码是什么(除了调用之外,该调用被转换为invokevirtual / static e.t.c)?我对将接收器加载到堆栈上的命令更感兴趣。

-显然有一个命令正在加载。

-另一个可能是另一个调用在堆栈上返回了一个refobject

-三,新指令。 (例如new A()。foo()。它被粘贴了,但是被构造函数消耗了)

-四个,也许(??)Dup。 (当具有a.foo(); a.bar();编译器是否有机会先生成aload然后生成dup而不是aload aload?)

我最大的问题是其余的dup命令。因为它们会洗牌。 javac何时产生它们?编译呼叫站点时会使用它们吗?

我试图找到没有运气的文档。然后找到了源代码,但是要花几天的时间进行深入研究。我相信Code.java and Gen.java文件负责翻译/编译过程。

1 个答案:

答案 0 :(得分:2)

javap可以使用

几乎所有任何字节码指令来生成引用,以加载接收器。

  • 加载,invokeX,新建+ dup
    您已经提到的那些。
  • getfield,静态的

    field.method();
    
  • aaload

    arr[index].method();
    
  • 新数组

    (new Object[0]).hashCode();
    
  • multianewarray

    (new byte[5][10]).getClass();
    
  • 检查广播

    ((List) obj).size();
    
  • ldc

    MyClass.class.getName();
    
  • aconst_null

    ((Object) null).getClass();
    
  • dup

    IntSupplier s = field::hashCode;
    

    这里dup + invokevirtual用于发出棘手的null检查:

    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