From: jinx@zurich.ai.mit.edu (Guillermo J. Rozas)
Newsgroups: comp.arch
Subject: Re: Ideas for new LISP Machines
Date: 11 Apr 92 20:48:30 GMT
	<JINX.92Apr11095717@chamarti.ai.mit.edu>
	<1992Apr11.161959.6435@athena.mit.edu>
Reply-To: jinx@zurich.ai.mit.edu
Organization: M.I.T. Artificial Intelligence Lab.
In-reply-to: jfc@athena.mit.edu's message of 11 Apr 92 16:19:59 GMT

In article <1992Apr11.161959.6435@athena.mit.edu> jfc@athena.mit.edu (John F Carr) writes:

*   The RS/6000 includes an environment pointer in all function pointers.
*   This doesn't add much cost because:

I assume you mean the standard calling convention, rather than the
architecture.

*	   (1) There is already an extra word in the function pointer
*	   which is used to make all code position-independent and support
*	   dynamic linking.

Yes, C/Unix has finally re-invented closures.  We may actually find
support for them in new hardware.  :-)
Now seriously, there are other simple ways of carrying around each
function's global pointer if that's the only thing that's needed, and
I would not be surprised if the C/Unix world re-invented them soon,
and forgot about closures until C++ re-invented them.

*	   (2) Only calls that use pointers suffer the penalty.  The vast
*	   majority of function calls are by name, and calls by name to a
*	   C function do not need to load an environment pointer.

Actually, that may be true of C, but not necessarily of other
languages.  Of course, the typical distance between C function calls
is so huge, that the overhead of loading the register, etc., is
probably negligible, but again, C is not the only language in the
universe.

The fact that most calls are by name is not relevant.  The issue is
whether most calls are to global procedures or to nested procedures.
After all, Pascal programs hardly ever call procedures in any other
way than by name, yet the environment pointer needs to be passed.

The fact that C programs only call global procedures is entirely
predictable given that C only allows global procedure definitions!
The problem with GNU C is that it wants to support first-class
Pascal-style nested procedures, among other reasons so that Pascal and
C can be completely inter-callable, and so that a Pascal compiler can
just be a trivial front-end for the compiler.

*	   (3) The load of register 11 is completely overlapped with other
*	   operations, so indirect calls are not slowed by the presence of
*	   an environment pointer.  The only cost is the extra word of memory.

Well, I don't believe that.  The pipeline slot taken by that
instruction is a slot that another instruction is not using; the
D-cache line that the pair is using is a D-cache line better used for
other purposes, etc.  In addition, there are indirect costs as well.
If procedures are just addresses of instructions, they can refer to
each other by their relative distance (known at link/load/gc time), so
there is no need for keeping pointers to each other, since they can be
generated if they are ever needed.  When procedures are implemented as
a structure containing an instruction address and an environment
pointer, each procedure must have a pointer to every other procedure
that it calls.

*   Adding an environment pointer to the standard function pointer format also
*   allows support of nested functions without using two pointer formats and
*   without generating code.

True, as long as every language and compiler uses that format.

Fortunately the RS/6000 designers also included the CLF instruction
(cache-line flush) which does precisely the right thing, so it is not
an issue on that architecture.