[Vm-dev] Max number of method arguments

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Tue Jan 8 22:30:11 UTC 2019


Le mar. 8 janv. 2019 à 23:07, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> a écrit :

>
>
> Le mar. 8 janv. 2019 à 22:51, Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com> a écrit :
>
>> Hi all,
>> particularly Clement and Eliot,
>>
>> One of the most annoying limit of bytecode is the number of arguments
>> (<16 in V3), not so much annoying for pure Smalltalk, but certainly so for
>> FFI (FORTRAN 77 lacks structures so existing code base often have functions
>> with many arguments).
>> For scientific Smalltalk, some of those old FORTRAN libraries are still
>> around nowadays (LAPACK is an example).
>>
>> I patched the old Squeak compiler in Smallapack to workaround this
>> limitation (it was easy enough to pass a single Array, and invoke FFI with
>> many args).
>> In modern Pharo flavour, this is more involved with the new OpalCompiler
>> (iit does not seem to be designed for extensibility as it seems necessary
>> to patch many pieces/subclasses for a single feature change...).
>>
>> But we now have Sista V1 bytecodes which removed a lot of limitations (#
>> inst vars, #literals, max jump offset ...). Alas I don't see a modified
>> limit for number of arguments (source:
>> https://hal.inria.fr/hal-01088801/document a bytecode set for adaptive
>> optimization): there is still a limit of 4 reserved bits in compiled method
>> header documented in link above.
>> Though, there is an adjacent unused bit now...
>> In Squeak,/Pharo, EncoderForSistaV1>>genSend:numArgs: suggests that the
>> limit is 31 (sic)
>>
>>     (nArgs < 0 or: [nArgs > 31]) ifTrue:
>>         [^self outOfRangeError: 'numArgs' index: nArgs range: 0 to: 31
>> "!!"].
>>
>> or at least 2047 if we believe code below:
>>
>>     "234        11101010    i i i i i j j j    Send Literal Selector
>> #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments"
>>
>>
>> https://github.com/pharo-project/pharo/blob/50992c3e5fed790b7e660954aee983f4681da658/src/Kernel-BytecodeEncoders/EncoderForSistaV1.class.st
>>
>> Pharo also limit the numArgs to 15 whatever the encoding in
>> CompiledMethod>>newBytes:trailerBytes:nArgs:nTemps:nStack:nLits:
>> primitive:
>>
>> https://github.com/pharo-project/pharo/blob/50992c3e5fed790b7e660954aee983f4681da658/src/Kernel/CompiledMethod.class.st
>>
>> But Squeak does not limit nArgs at all in
>>
>> EncoderForSistaV1>>computeMethodHeaderForNumArgs:numTemps:numLits:primitive:
>>
>> So my questions:
>> - is that doc up-to-date?
>> - if so, couldn't we expand the limit to 31 args by using the unused bit?
>>
>> Note: there is another unused bit in V3 (not adjacent), and the double
>> extended (send) byte code has room for 31 args in V3 too, since only the
>> first 3 bits of second byte encode the type of operation...
>>
>
> Confirmed in VMMaker: max num args is still 15 in CompiledMethod header
>
> StackInterpreter>>argumentCountOfMethodHeader: header
>     <api>
>     ^header >> MethodHeaderArgCountShift bitAnd: 16rF
>
> I see that this decoding is shared whatever byte-code alternative...
>

And the other unused bit (flag, position 30, 0-based) is not always
unused... See maybeFlagMethodAsInterpreted:

         realHeader := realHeader bitOr: (objectMemory integerObjectOf: 1
<< MethodHeaderFlagBitPosition).

Why do we flag the interpreted methods?
I had the impression that the offset was off by 1

    MethodHeaderFlagBitPosition := 28 + tagBits.

but we are tricky, since integerObjectOf: will perform the missing 1-bit
shift...
This way, Newspeak that is using both bits 29-30 has the right offset. Ouch.
I now see no room left in that header...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20190108/e0399602/attachment-0001.html>


More information about the Vm-dev mailing list