A bug with automatic variables and finally
Paul N. Hilfinger
hilfingr at CS.Berkeley.EDU
Fri May 2 19:10:36 PDT 1997
> On Thu, 1 May 1997, Robert S. Thau wrote:
> > You mean asynchronous like one thread can generate an exception in
> > another? Given this is the case how the hell do they write an
> > to be atomic (I think they say they are somewhere)?
an "instruction", I assume? If you're writing an interpreter, it's
easy; causing an exception consists of setting a bit in the
interpreter's state for a thread, which the interpreter checks at the
top of the instruction cycle.
> What about catching such asynchronous exceptions only at special points,
> such as (a) method invokations and (b) backward jumps? This allows for
> lots of optimizations, because all other places where exceptions can occur
> (such as an integer division) are known. Furthermore this ensures that
> the code "checks for exceptions" reasonably often (at least once per
This is a standard technique that has much going for it.
> What remains is a good way to delay those asynchronous exceptions. I'd
> propose examining the code that the exception is thrown to, and putting in
> some kind of breakpoints at the locations where it can be caught. Those
> breakpoints are removed after the exception has been caught. This is of
> course only a rough scheme.
Or, if you can afford to burn a register, you can establish a
particular register that the would-be exception-raiser sets and that
gets tested (presumably cheaply, since it's a register) at appropriate
points. A global memory location will also serve, if it can be
addressed cheaply enough. These schemes are simpler to get right, but
not as fast as yours (in the normal case).
The basic idea is to push the literal definition of when an exception
must occur as far as legally possible. The justification is that
throwing any exception other than ThreadDeath is supposed to be
"unusual"---mildly deprecated, I guess. Throwing ThreadDeath,
furthermore, is not generally something that has to happen instantly.
One can actually push the legal definitions quite far, because of the
liberality with which the Java designers have defined scheduling and
priorities. That is, you can simply invent the fiction that, just
before the call on kill(....) the scheduler suddenly intervenes (just
happened to be in the neighborhood) and lets the soon-to-be-killed
thread run. The priority rules allow this to happen EVEN WHEN the
killer thread has a higher priority than the doomed one (see section
17.12 of the RM, last paragraph).
More information about the kaffe