StgRun and reserved C stack space

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

StgRun and reserved C stack space

Stefan Schulze Frielinghaus
Hi all,

I'm trying to understand how StgRun/StgReturn are supposed to be implemented.
My current understanding is that StgRun is called from C land in order to save
all callee-saved registers, allocate some stack space, and then finally jump to
an STG function.  StgReturn is the counterpart of StgRun and is called from STG
land in order to restore all callee-saved registers, free the previously
allocated stack space, and finally return to C land.

Assuming that my intuition is correct I still have some concerns regarding the
stack space which is allocated by StgRun.  StgRun allocates
RESERVED_C_STACK_BYTES many bytes on the C stack.  However, I cannot see how an
STG function is supposed to access this reserved area since no pointer is
derived or whatsoever.  Does an STG function make use of the C stack pointer
and assume that the reserved area is at the very bottom of the stack?

Lets make an example.  Assume the C ABI demands that every function
allocates a Register Save Area (RSA for short) at the bottom of a stack
frame which may be used by a subsequent C function.  That means a caller
allocates some stack space for its callee.  This area must be below the
local variable and parameter area which means it is at the very bottom
of a stack frame.  A C stack frame then looks as follows:

      .                     .
      .                     .
      | previous frame      |
      +---------------------+
      | local variables     |
      +---------------------+
      | parameter area      |
      +---------------------+
      | register save area  |
      +---------------------+  <---+ SP

Thus StgRun must also allocate a register save area which is used by subsequent
C functions.  An example stack while calling StgRun could look as follows:

      .                     .
      .                     .
      |                     |
      +---------------------+
RSA1  | register save area  |
      | used by StgRun      |
      +---------------------+ xxx
      |                     |   xx
      |                     |    xx
      |                     |     xx
      |                     |     xx
      |                     |      xxxxxx RESERVED_C_STACK_BYTES
      |                     |     xx
      |                     |     xx
      |                     |    xx
      |                     |   xx
      +---------------------+ xxx
RSA2  | register save area  |
      | for further C calls |
      +---------------------+  <---+ SP

RSA1 is allocated by the caller of StgRun and is used by StgRun in order to
save all callee-saved registers.  StgRun itself then allocates
RESERVED_C_STACK_BYTES many bytes and RSA2.  RSA2 will be used by subsequent C
functions which are called from STG land.

Thus coming back to my initial question how is an STG function supposed to know
where the reserved area starts?  One way would be to use SP + len(RSA2) but
this would mean an STG function is aware of the register in which the C stack
pointer is hold and the length of a register save area.  I didn't find anything
which suggests this while skimming over the code.

Many thanks and kind regards,
Stefan
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

RE: StgRun and reserved C stack space

GHC - devs mailing list
Perhaps Simon Marlow, or others, may be able to help?

It would be good to capture the answers somewhere, perhaps in the GHC Commentary?
https://gitlab.haskell.org/ghc/ghc/wikis/commentary

Simon

| -----Original Message-----
| From: ghc-devs <[hidden email]> On Behalf Of Stefan Schulze
| Frielinghaus
| Sent: 22 June 2019 10:23
| To: [hidden email]
| Subject: StgRun and reserved C stack space
|
| Hi all,
|
| I'm trying to understand how StgRun/StgReturn are supposed to be
| implemented.
| My current understanding is that StgRun is called from C land in order to
| save all callee-saved registers, allocate some stack space, and then
| finally jump to an STG function.  StgReturn is the counterpart of StgRun
| and is called from STG land in order to restore all callee-saved
| registers, free the previously allocated stack space, and finally return
| to C land.
|
| Assuming that my intuition is correct I still have some concerns regarding
| the stack space which is allocated by StgRun.  StgRun allocates
| RESERVED_C_STACK_BYTES many bytes on the C stack.  However, I cannot see
| how an STG function is supposed to access this reserved area since no
| pointer is derived or whatsoever.  Does an STG function make use of the C
| stack pointer and assume that the reserved area is at the very bottom of
| the stack?
|
| Lets make an example.  Assume the C ABI demands that every function
| allocates a Register Save Area (RSA for short) at the bottom of a stack
| frame which may be used by a subsequent C function.  That means a caller
| allocates some stack space for its callee.  This area must be below the
| local variable and parameter area which means it is at the very bottom of
| a stack frame.  A C stack frame then looks as follows:
|
|       .                     .
|       .                     .
|       | previous frame      |
|       +---------------------+
|       | local variables     |
|       +---------------------+
|       | parameter area      |
|       +---------------------+
|       | register save area  |
|       +---------------------+  <---+ SP
|
| Thus StgRun must also allocate a register save area which is used by
| subsequent C functions.  An example stack while calling StgRun could look
| as follows:
|
|       .                     .
|       .                     .
|       |                     |
|       +---------------------+
| RSA1  | register save area  |
|       | used by StgRun      |
|       +---------------------+ xxx
|       |                     |   xx
|       |                     |    xx
|       |                     |     xx
|       |                     |     xx
|       |                     |      xxxxxx RESERVED_C_STACK_BYTES
|       |                     |     xx
|       |                     |     xx
|       |                     |    xx
|       |                     |   xx
|       +---------------------+ xxx
| RSA2  | register save area  |
|       | for further C calls |
|       +---------------------+  <---+ SP
|
| RSA1 is allocated by the caller of StgRun and is used by StgRun in order
| to save all callee-saved registers.  StgRun itself then allocates
| RESERVED_C_STACK_BYTES many bytes and RSA2.  RSA2 will be used by
| subsequent C functions which are called from STG land.
|
| Thus coming back to my initial question how is an STG function supposed to
| know where the reserved area starts?  One way would be to use SP +
| len(RSA2) but this would mean an STG function is aware of the register in
| which the C stack pointer is hold and the length of a register save area.
| I didn't find anything which suggests this while skimming over the code.
|
| Many thanks and kind regards,
| Stefan
| _______________________________________________
| ghc-devs mailing list
| [hidden email]
| https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.hask
| ell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-
| devs&amp;data=02%7C01%7Csimonpj%40microsoft.com%7C9b1c5c94f5a14f3d11c308d6
| f6f34a3d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636967922119470764&a
| mp;sdata=cYAlP9xb%2F%2FeoYy%2Bq4M66IomjxX90HtwgPpSf2mvYX5U%3D&amp;reserved
| =0
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs