Newsgroups: comp.arch
Path: utzoo!henry
From: henry@utzoo.uucp (Henry Spencer)
Subject: Re: register save/restore
Message-ID: <1988Nov6.025231.17965@utzoo.uucp>
Organization: U of Toronto Zoology
References: <3300037@m.cs.uiuc.edu> <5938@killer.DALLAS.TX.US> <7580@aw.sei.cmu.edu> <3473@pt.cs.cmu.edu>
Date: Sun, 6 Nov 88 02:52:31 GMT

In article <3473@pt.cs.cmu.edu> bsy@PLAY.MACH.CS.CMU.EDU (Bennet Yee) writes:
>It's interesting to examine the ACIS implementation of longjmp/setjmp for
>the IBM RTs.  The standard procedure call convention is callee-save, and
>longjmp does NOT unwind the stack.  Contrast this with the Vaxen BSD
>implementation of longjmp/setjmp, which DOES unwind the stack.  Vaxen BSD,
>of course, uses callee-save too.  What is the difference?  Well, for the IBM
>RTs, your registers have the same values as when they returned from the
>setjmp.  On Vaxen, your registers have the same values as they had when you
>called the next function from within the same function that called the
>setjmp.  So depending on one or the other behaviour for your register
>variables is not safe.  It's a minor but significant semantic difference.
>[Anybody know what POSIX decided for this?]

X3J11, not POSIX, is the relevant group here.  And X3J11 has wimped out on
it, in a big way:  the values of *any* local variables (not just register
variables -- the compiler may be quietly promoting things into registers!)
that have changed since the setjmp are *indeterminate* after a longjmp,
unless the variables are declared "volatile".  Note, there is no guarantee
that you get *either* of the above cases!  The values may even be trash!

Some of us thought this was a damn stupid idea, since it invalidates
essentially every existing program that uses setjmp/longjmp, but we were
unable to convince X3J11 of this.  They claim that this is a "quality
of implementation" issue.

>Now, how to avoid unwinding the
>stack and still retain the same semantics?  It's actually not hard -- given
>that, for those ``other'' languages at least, GOTO and RAISE are part of the
>language, the compiler can just always save the contents of register
>variables before calling other functions _only for those functions that
>contain GOTO or RAISE_, and restore the registers variables when the
>exception occurs...
>
>Of course, it's hard to argue a similar case for C, since setjmp/longjmp is
>NOT part of the language...

Au contraire, it *is* part of the language.  Realistically, the major C 
library functions have to be considered part of the language.  Most every C
implementor has cursed this fact, since it puts significant constraints on
calling-sequence design.  X3J11 has put enough constraints on the invocation
of setjmp, in fact, that the compiler can do the same sorts of things as it
could for a language with built-in setjmp/longjmp.  This is important,
because it's the only sane way to handle setjmp/longjmp if you are doing
fancy register allocation and can't do a stack unwind.  (Fancy register
handling means non-register variables, which most users expect are safe,
are in fact in danger.  Stack unwinding relies on the stack layout being
either invariant or self-describing [pdp11 and vax respectively], and is
not possible with efficient calling sequences on most modern machines.)
-- 
The Earth is our mother.        |    Henry Spencer at U of Toronto Zoology
Our nine months are up.         |uunet!attcan!utzoo!henry henry@zoo.toronto.edu
