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