guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

wip-rtl return location


From: Andy Wingo
Subject: wip-rtl return location
Date: Thu, 02 Aug 2012 16:29:49 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)

Hi,

Some brief thoughts on the wip-rtl branch.  Currently it has this
strange "return location" thing, where it specifies the register(s) to
which to return value(s), and the number of expected values and whether
it expects a rest list or not.  Problem is, this return location is like
a little program that needs to be interpreted at runtime.  Worse, it
seems to assume that return values will have to be passed in memory.

Instead I'd rather just use Dybvig's suggestion: every call instruction
is preceded by an MV return address.  For e.g. (values (f)), calling `f'
would be:

    ...
    goto CALL
MVRA:    
    truncate-and-jump RA
CALL:
    call f
RA:
    return

So the overhead of multiple values in the normal single-value case is
one jump per call.  When we do native compilation, this cost will be
negligible.  OTOH for MV returns, we return to a different address than
the one on the stack, which will cause a branch misprediction (google
"return stack buffers" for more info).  Of course this is not relevant
to the interpreter, because all of these branches are indirect, but it
will be in the future, so it's a good idea to think about these things
now.  With this design, the caller is responsible for handling MV
returns, not the callee.

Anyway, MV return will cause a branch misprediction.  Oh well.  I think
we can live with it.  Single-valued returns are the common case, and
they will be predicted correctly.

So, another thing.  The reason for the previous "return location" design
was because I wanted to have just two registers reserved by the
implementation: the instruction pointer and the frame pointer.  Wanting
an IP is obvious.  It's important to locate frame pointers so that
various pieces of code can walk the stack frames: for example the
delimited continuation code, the backtrace printer, the debugger, etc.
It's possible to just using a stack pointer and use dynamic tables to
find where the frame pointer is, like the x86-64 architecture does (or
-fomit-frame-pointer), but that requires more sophistication on the part
of the runtime, and I don't think we're really ready for that right now.

As I said, I wanted just the IP and the FP.  I didn't want an SP because
it causes so much performance noise in the current VM.  But then I
realized that in the RTL VM, it doesn't need to be accessed frequently,
because more values are addressed against the FP, and we're not pushing
and popping temporaries.  So we can actually keep it around, and it
might not need to be in a register.  It retains its useful
characteristics of allowing variable-sized data to be (temporarily)
allocated on the stack, as in procedure calls or MV returns, and as a
stack delimiter for GC.

In summary:

  - I will remove the "return location" stuff from wip-rtl;

  - All calls will be mv-calls

  - MV returns will return to 1 instruction before the RA

  - All calls will be preceded by a jump over the MVRA

  - Eventually we can remove the MVRA slot from stack frames, because it
    is computable from the RA

  - The stack pointer is back in town!

Andy
-- 
http://wingolog.org/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]