spockwang
spockwang

Reputation: 917

Argument count limit of methods in Smalltalk-80 implementation

The maximum number of arguments of a method is limited to 2^5-1(i.e. 31) because there is only 5 bits to encode the number of arguments in a compiled method as illustrated in Figure 27.4 of the blue book. But the double extended send bytecode has 8 bits to encode the number of arguments (see the definition of doubleExtendedSendBytecode here), which means I can send as many as 2^8-1 (i.e. 127) arguments to a message (using perform: or the statement will not be compiled). Is this a contradiction? I think the bytecode uses too many bits to encode the number of arguments.

Upvotes: 4

Views: 267

Answers (2)

Stephan Eggermont
Stephan Eggermont

Reputation: 15917

The actual number of arguments used is mostly small. The number of arguments of CompiledMethods in a Moose 4.6 Image I have here:

|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

Upvotes: 1

Tobias
Tobias

Reputation: 3110

Yes, this is a contradiction but it did not yet matter enough.

Also, the number of arguments in a methods is bounded to the maximum number of temporary variables in a method, too, which in most Smalltalks happen to be 2^8-1.

There is another part to that:

In Squeak, the number of arguments is actually restricted to 15 (2^4-1), and also has only a nibble (4 bit) of space in the method header. As the comment of Squeak's CompiledMethod states:

(index 18)  6 bits: number of temporary variables (#numTemps)
(index 24)  4 bits: number of arguments to the method (#numArgs)

with the #numTemps including the number of arguments, too.

Long story short, yes, the doubleExtendedSendBytecode could encode more arguments than actually expressible in a CompiledMethod.

This is one of the reasons it was replaced in Squeak by the doubleExtendedDoAnything bytecode that can do more than just sends, but limits the number of arguments to 2^5-1 (which is still more than the CompiledMethod can encode, but it is not unlikely that CompiledMethod will change in the foreseeable future to encode more than 15 arguments).

Upvotes: 4

Related Questions