我试图理解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为计数值贡献两个单位,而
其他任何类型的参数都贡献一个单位。此信息可以
也可以从所选方法的描述符中得出。的
冗余是历史性的。