Related articles |
---|
setjmp/longjmp implementations hbaker@netcom.com (1994-02-16) |
Summary of setjmp/longjmp responses hbaker@netcom.com (1994-02-17) |
Re: Summary of setjmp/longjmp responses mueller@nu.cs.fsu.edu (1994-02-18) |
Re: Summary of setjmp/longjmp responses pardo@cs.washington.edu (1994-02-18) |
Re: Summary of setjmp/longjmp responses [SPARC] markt@harlequin.co.uk (1994-02-22) |
Summary of setjmp/longjmp responses meissner@osf.org (1994-02-22) |
Newsgroups: | comp.compilers |
From: | pardo@cs.washington.edu (David Keppel) |
Keywords: | C, sparc |
Organization: | Computer Science & Engineering, U. of Washington, Seattle |
References: | 94-02-097 94-02-117 |
Date: | Fri, 18 Feb 1994 20:55:30 GMT |
hbaker@netcom.com (Henry G. Baker) writes:
>[SPARC register windows make `longjmp' a headache. `longjmp' traps
> to flush registers, even if they are all dead; this sounds like a
> good time for compiler help.]
Sorry, but you're basically out of luck here, the compiler can't help
you. There are two choices (three really):
- Starting with the topmost stack frame, use the SPARC `restore'
instruction to iterate through the stack frames until you get to
the one where you did a `setjmp'. If there are only a few
iterations (e.g., the `setjmp' was in your immediate caller) then
you probably won't trap. However, if the `longjmp' destination is
a long way up the stack then you will take window underflow traps
(possibly several) as you walk back up the stack.
- Trap and flush register windows.
The problem with SPARC register windows, in this case, is that there is no
way -- from user mode -- to determine which register windows are live and
which are dead, and doing a longjmp without updating all of the live
register windows is fatal. For example, if the top-level frame and its
caller are both cached in windows, you might try to update the top-level
frame to be the `longjmp' target frame (the one where the `setjmp'
occured). However, a subsequent trap or timer expiration will write back
the (old) caller's stack frame to the stack location where it used to be,
because the hardware still indicates that register window is live. While
it is possible that the caller is above the current top-of-stack, it is
also possible that it's somewhere in the current stack. It's also the
case that you can't test (from user mode) the current number of live
register windows.
The reason that second alternative, trapping, works is that the trap
handler will write back all the register frames and then mark only the
current one as valid. When the trap returns you can change the current
frame within user space and even if there's a subsequent trap (timer
expiration, etc.) the other frames are all marked as invalid, so there's
no chance they'll get written and clobber the stack. (It might seem like
a good idea to omit the flushing and just mark the other windows as
invalid, but then you're left with the problem that unless you know in
advance how many stack frames you're popping, you don't know whether any
of the cached register windows actually *are* ones you want to save.)
The third `longjmp' implementation choice is to use both of the above
techniques: during a `longjmp', iterate through, say, 3 stack frames (the
right number depends on the processor implemtnation, on how the OS spills
and restores on window overflow and underflow traps, and on the
application's calll/return behavior) and if after 3 frames you still
haven't gotten to the desired frame, then trap and flush the register
windows. You can arrange that this is always a win for n=1 (you can
actually examine your caller's sp without trapping) but may be a loss for
n>1.
You face roughly the same problems here as when doing thread context
siwtches; I'll refer you to my TR on user-space SPARC threads, (called
_Register Windows and User-Space Threads on the SPARC_) available via
anonymous ftp from `ftp.cs.washington' (128.95.1.4) in the subdir.
`tr/1991/08/UW-CSE-91-08-01.PS.Z'.
;-D on ( Flush with excitement ) Pardo
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.