[Vm-dev] Max number of method arguments

Eliot Miranda eliot.miranda at gmail.com
Tue Jan 8 22:41:50 UTC 2019


On Tue, Jan 8, 2019 at 2:39 PM Eliot Miranda <eliot.miranda at gmail.com>
wrote:

> Hi Nicolas,
>
> On Tue, Jan 8, 2019 at 2:30 PM Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com> wrote:
>
>>
>> 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?
>>
>
> This is for me for profiling.  Because Cog is a hybrid interpreter+JIT it
> can use the policy of avoiding JITting a method until it is found in the
> method lookup cache, or (to make sure that doits run at full speed)
> evaluated by one of the withArgs:executeMethod: primitives.  This means
> that the JIT doesn't waste time JITing huge methods that are only evaluated
> one e on system startup.  JITting is like a very slow interpretation, so it
> doesn't make sense to JIT a method that is simply a long sequence of
> statements if it is only used once; it will be much quicker and use much
> less space to simply interpret it once, instead of JITing it and then
> evaluating it once.  Further, the VM won't JIOT anything with a certain
> number of literals anyway.  This is a startup parameter and defaults to 60
> literals.  Any method with more than 60 literals won't be JITted.
>

Note also that the interpreter counts backward branches and if it finds it
is in a method that is looping a lot (default 20 iterations IIRC) it will
JIT compile the method and switch to the JIT version of it on the 20th
iteration.  This avoids the VM getting stuck interpreting a method that
loops forever.


> But I wanted to be sure that this policy was not affecting any methods
> that are performance critical.  So I added the facility top flag
> interpreted methods as I can see which methods are executed that the VM
> chooses not to JIT.
>
> Back in 2009/2010 I did indeed use the facility to check and found that my
> intuitions were correct and that the policy is a good one (although our
> including of the selectors for inlined messages such as ifTrue:ifFaklse: et
> al might mean we want to increase the limit on number fo literals for
> JITing as little, 65 perhaps?).
>
> 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...
>>
>
> _,,,^..^,,,_
> best, Eliot
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20190108/839b0a51/attachment.html>


More information about the Vm-dev mailing list