4

方法的最大参数数量被限制为2^5-1(即 31),因为只有 5 位来编码编译方法中的参数数量,如蓝皮书的图 27.4 所示。但是双扩展发送字节码有 8 位来编码参数的数量(参见doubleExtendedSendBytecode 这里的定义),这意味着我可以向消息发送多达2^8-1(即 127 个)参数(使用perform:,否则语句将不会被编译)。这是矛盾吗?我认为字节码使用太多位来编码参数的数量。

4

2 回答 2

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(这仍然超过了CompiledMethod可以编码,但在可预见的情况下,这种情况不太可能CompiledMethod发生变化未来编码超过 15 个参数)。

于 2013-07-31T15:42:17.907 回答
1

实际使用的参数数量大多很少。我在这里拥有的 Moose 4.6 图像中 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
于 2013-08-03T22:01:25.603 回答