invokeinterface - 计数值

invokeinterface - count value

我试图理解 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 但在 68 中是 1:应该为 1 但为 2).

根据JVM doc

The count operand is an unsigned byte that must not be zero

这就是为什么许多论点似乎是 nargs + 1 的原因吗?

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

其实count并不是参数的个数,而是传递参数需要的栈槽的个数。实际上,现代 JVM 通常不使用此字节,请参阅 notes:

The count operand of the invokeinterface instruction records a measure of the number of argument values, where an argument value of type long or type double contributes two units to the count value and an argument of any other type contributes one unit. This information can also be derived from the descriptor of the selected method. The redundancy is historical.