Exception handling complicates the runtime system:
-
We must ensure that we can find the right exception handler
block in the current function/method if there is one.
-
If not, we must remove one activation record and look for
exception handler blocks in the preceding activation record.
-
Moreover, we must ensure execution of each dynamically
enclosing
finally
block.
A simple strategy is to maintain a stack of exception
handlers:
-
Whenever we enter a new exception handler block, we push a
new handler onto the stack.
-
As with case statements, there are several implementation
strategies: the handler might be a pointer to code, or it
might be a pointer to a jump table with an entry for each
exception handled.
-
In addition, handlers must be inserted to remove activation
records when a function/method ends because of an exception.
This strategy has significant runtime costs, because we must
maintain the stack of exception handlers as the normal flow
of execution passes through them. Thus, we are constantly
paying for the rare case when an exception is thrown.