我试图理解JVM字节码,但是遇到了以下代码:

58: invokeinterface #5,  1            // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
63: invokedynamic #6,  0              // InvokeDynamic #0:test:()Ljava/util/function/Predicate;
68: invokeinterface #7,  2            // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;


似乎count值始终为nargs + 1(在58:应为0但为1,在68:应为1但为2)。

根据JVM doc


  计数操作数是一个无符号字节,不能为零


这就是为什么许多参数看起来都是nargs + 1的原因吗?

最佳答案

this对象(在JVMS中称为objectref)始终是invokeinterface的第一个隐式参数。它与其他nargs参数一起在操作数堆栈上传递。

实际上,count不是参数的数量,而是传递参数所需的堆栈插槽的数量。实际上,现代JVM通常不使用此字节,请参见notes


  invokeinterface指令的count操作数记录一个小节
  参数值的数量,其中long类型的参数值
  或类型double为计数值贡献两个单位,而
  其他任何类型的参数都贡献一个单位。此信息可以
  也可以从所选方法的描述符中得出。的
  冗余是历史性的。

09-10 08:20
查看更多