[net.lang] Why displays are always faster than static links

baskett@decwrl.UUCP (Forest Baskett) (10/22/83)

Displays are always faster than static links (except in pathological
cases) provided the compiler exercises a little bit of intelligence
when generating code for procedure entry and exit.  The previous
discussions make clear that displays are faster for referencing
non-locals/non-globals but some of them suggest that procedure
calling suffers more from displays than from static links.  In fact,
the reverse is usually true.  Here's why.  Most procedures do not do
non-local/non-golbal referencing so if we could find a way to call
and return from those procedures without any action related to
lexical scoping, we would, 99% of the time, be on the same footing
as languages without lexical scoping (e.g., C).  The display enables
us to do that if the compiler cooperates.  If I'm a procedure and I
have local variables that some other proceudre is going to access
(notice that this other procedure must be defined inside me), then
when I am entered, I must save the display pointer to my lexical level
that existed at entry and replace it with a pointer to my locals.  When
I exit, I need to restore the old display pointer.  Now here's the flip
side.  If I'm a procedure and NO OTHER procedure references my locals
(the usual case), then I can blithly DO NOTHING about the display pointer
to my lexical level.  I can leave it along, not touch it, not execute
any instructions associated with it.  When I exit, everything will be fine,
no matter who I've called in the meantime.  (This is an inductive argument.)
Can the compiler easily tell if no other procedures reference my locals?
Well, some compilers actually can and most compilers can be fixed so
that they can.  Remember that the only procedures that can reference my
locals are those that are defined INSIDE me.  Thus when the compiler gets
to the point of generating code for my body, it will have seen all the
procedures that have any chance of referencing my locals.  If it watches
for non-local/non-global references as it processes those procedures and
marks the current procedure being compiled at a lexical level that does
experience a non-local/non-global reference, then when it gets to my body
there will be a flag that tells it whether to bother with the display or
not on my entry and exit sequences.  A less demanding but almost as
effective strategy is to just key off the presence or absence of 
enclosed procedures.  If there are no procedures defined inside me
(a very common case), then I don't need to do display maintenance.

I've used this trick on several compilers now and it works and is very
effective.  I can't imagine ever using static links.  I don't know
where this trick comes from but I'm pretty sure it's pretty old.
I have a very foggy recollection of Edsgar Dijkstra telling Burroughs
Corporation how to do it for their Algol 60 compiler.  It's too bad
it doesn't ever seem to be mentioned in compiler books.

Forest Baskett
...!decwrl!baskett

bhaskar@fluke.UUCP (K.S. Bhaskar) (10/25/83)

yes, i also used the display optimization technique mentioned in an
interpreter that i wrote some years ago, and, like all hackers, i
(re-)invented it from scratch!  actually, maybe i am missing something, but
with any machine with a reasonable stack architecture (which eliminates only
one major line of machines), saving and restoring a display should actually
take less work than setting up a static link, since displays are global and
the static scope level of a procedure is known at compile-time and is constant.

{allegra,lbl-csam,microsoft,sb1,uw-beaver}!fluke!bhaskar

mjl@ritcv.UUCP (Mike Lutz) (10/26/83)

I sent a note to utcsrgv!peterr on this subject, showing one case where I
think static links are a win over saving the previous value of for display
level 'N' in the activation record of a procedure called at level 'N'. (Whew
-- sorry about the run-on sentence.)

The problem arises when formal procedure parameters are supported in the
language.  In such cases, when a procedure is passed as an argument, the actu-
al information passed must include the entry point to the procedure's code,
its lexical level, and some encoding of the accessing environment at the time
of the call.  It is this last requirement which motivates the use of static
links.  With static links, all that need be passed is a pointer to the sur-
rounding parent's activation record; when the procedure is eventually invoked,
the display can then be reconstructed by traversing the static link chain be-
ginning at this point.  Without the static chain, the entire display up to and
including the parent's lexical level must be passed.

One must, of course, evaluate the cost/benefit ratio in light of the expected
frequency of such constructions.  It is worth noting that there are program-
ming styles that attempt to provide a modicum of information hiding in block
structured languages by using procedure parameters.

If anyone has a solution to this problem that is both space efficient and
doesn't require static links, I'd like to know about it.

Mike Lutz
ritcv!mjl

paulh@tektronix.UUCP (Paul Hoefling) (11/03/83)

>  actually, maybe i am missing something, but
>  with any machine with a reasonable stack architecture (which eliminates only
>  one major line of machines), saving and restoring a display should actually
>  take less work than setting up a static link, since displays are global and
>  the static scope level of a procedure is known at compile-time and is constant.

There is one minor problem with this statement, the static scope level of all
procedures is known at compile time *only* if the entire program is compiled
at once (ala standard Pascal) with a language that allows separate compilation,
this ain't necessarily so...

Happy computing...

Paul Hoefling
(...!teklabs!tektronix!paulh - usenet)
(paulh at tektronix - csnet)
(AB00PLH on Cyber)