[Vm-dev] JIT stack discipline from caller's POV

Eliot Miranda eliot.miranda at gmail.com
Thu Mar 21 17:04:44 UTC 2013


On Thu, Mar 21, 2013 at 7:19 AM, Igor Stasenko <siguctua at gmail.com> wrote:

>
> Hi, Eliot & all
>
> i just want to summarize the SimpleStackBasedCogIt stack discipline,
> please correct me if i wrong.
>
> On call:
>
> If number of arguments is 0 or 1 (just receiver or receiver + 1 arg),
> caller uses registers to pass them:
> EDX for receiver
> ESI for arg1
>
> If number of arguments is > 1
> then caller pushes all arguments on stack.
>
> After return:
> - caller expecting result in EDX
> - the stack is cleaned by callee (by popping args from stack), but
> only for those which was pushed (so in case of <=1 arguments there's
> nothing to pop)
>
>
> Am i correct?
>

Nearly ;)  First of all you're describing the Smalltalk-to-Smalltalk
calling convention of StackToRegisterMappingCogit.

The st-to-st calling convention for SimpleStackBasedCogIt is

on call ReceiverResultReg (edx on x86) contains the receiver, and the
receiver and arguments are all on the stack, receiver furthest from
top-of-stack.
If the number of arguments is 3 or greater then the argument count is
passed in SendNumArgsReg (this is for the linking run-time routine; it is
ignored in linked sends).
on return result is in ReceiverResultReg.  The callee removes arguments
from the stack.

The st-to-st calling convention for StackToRegisterMappingCogit is:

- if the number of arguments is less than or equal to numRegArgs then the
receiver and arguments are passed in registers.  numRegArgs is currently 1,
but will become 2 once the code generator generates machine code primitives
which take 2 arguments (i.e. once the object representation makes it
feasible to implement at:put: in machine code numRegArgs will be raised to
2).  The receiver is passed in ReceiverResultReg, the first argument in
Arg0Reg (esi on x86) and the second argument (if numRegArgs = 2) in Arg1Reg
(edi on x86).

- if the number of arguments is greater than numRegArgs then the calling
convention is as for SimpleStackBasedCogIt; ReceiverResultReg contains the
receiver, and the receiver and arguments are all on the stack, receiver
furthest from top-of-stack.  If the argument count is > 2 then argument
count is passed in SendNumArgsReg.

On return the result is in ReceiverResultReg.  The callee removes arguments
from the stack.

Note that if a machine code method contains a call to an interpreter
primitive it will push any register arguments on the stack before calling
the primitive so that to the primitive the stack looks the same as it does
in the interpreter.

Note that this *is not* the calling convention used to call routines in the
interpreter; the Cogits use the C calling convention for those.

Note that what you say above "- the stack is cleaned by callee (by popping
args from stack), but only for those which was pushed (so in case of <=1
arguments there's nothing to pop)" is not really correct.  The prolog of a
method will push register arguments on the stack if the method builds a
frame.  Frameless methods (certain simple methods that don't contain sends
or any bytecode that can provoke a send) won't push anything and will
operate on their register arguments.  Methods containing a machine code
primitive (e.g. SmallInteger>>#+) will operate on the register arguments
and return their result in ReceiverResultReg unless the primitive fails, in
which case the arguments will be pushed in the post-primitive prolog.  So
once a method is activated its frame layout does not depend on whether it
has register arguments.

Clear?
-- 
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20130321/c29eed98/attachment.htm


More information about the Vm-dev mailing list