方法的最大参数数量限制为2^5-1
(即31),因为编译方法中的参数数量只有5位,如Figure 27.4 of the blue book所示。但是双扩展发送字节码有8位来编码参数的数量(参见doubleExtendedSendBytecode
here的定义),这意味着我可以发送尽可能多的2^8-1
(即127)个参数消息(使用perform:
或不会编译语句)。这是矛盾吗?我认为字节码使用了太多的位来编码参数的数量。
答案 0 :(得分:4)
是的,这是一个矛盾,但它还不够重要。
此外,方法中的参数数量也限制为方法中临时变量的最大数量,在大多数Smalltalks中恰好是2^8-1
。
还有另一部分:
在Squeak中,参数的数量实际上限制为15(2^4-1
),并且方法头中只有一个半字节(4位)的空间。
正如Squeak CompiledMethod
所述的评论:
(index 18) 6 bits: number of temporary variables (#numTemps)
(index 24) 4 bits: number of arguments to the method (#numArgs)
#numTemps
包括参数的数量。
长话短说,是的, doubleExtendedSendBytecode
可编码的参数多于CompiledMethod
中实际可表达的参数。
这是它在Squeak中被doubleExtendedDoAnything
字节码替换的原因之一,它不仅仅是发送,而是将参数的数量限制为2^5-1
(仍然< / em>超过CompiledMethod
可以编码,但CompiledMethod
在可预见的将来不会改变以编码超过15个参数)。
答案 1 :(得分:1)
使用的实际参数数量很少。 Moose 4.6 Image中CompiledMethods的参数个数我在这里:
|bag|
bag := IdentityBag new.
CompiledMethod allInstances do:[ :element | bag add: element numArgs ].
bag sortedCounts
52006 -> 0
25202 -> 1
6309 -> 2
2133 -> 3
840 -> 4
391 -> 5
191 -> 6
104 -> 7
61 -> 8
12 -> 9
11 -> 10
5 -> 11
4 -> 12
3 -> 13
2 -> 15
1 -> 14