Meeting notes: Implementation idea: Exception Handling in C++/Java

The 5/18/01 meeting discussed ideas for implementing exceptions in LLVM.
We decided that the best solution requires a set of library calls provided by
the VM, as well as an extension to the LLVM function invocation syntax.

The LLVM function invocation instruction previously looks like this (ignoring
types):

  call func(arg1, arg2, arg3)

The extension discussed today adds an optional "with" clause that 
associates a label with the call site.  The new syntax looks like this:

  call func(arg1, arg2, arg3) with funcCleanup

This funcHandler always stays tightly associated with the call site (being
encoded directly into the call opcode itself), and should be used whenever
there is cleanup work that needs to be done for the current function if 
an exception is thrown by func (or if we are in a try block).

To support this, the VM/Runtime provide the following simple library 
functions (all syntax in this document is very abstract):

typedef struct { something } %frame;
  The VM must export a "frame type", that is an opaque structure used to 
  implement different types of stack walking that may be used by various
  language runtime libraries. We imagine that it would be typical to 
  represent a frame with a PC and frame pointer pair, although that is not 
  required.

%frame getStackCurrentFrame();
  Get a frame object for the current function.  Note that if the current
  function was inlined into its caller, the "current" frame will belong to
  the "caller".

bool isFirstFrame(%frame f);
  Returns true if the specified frame is the top level (first activated) frame
  for this thread.  For the main thread, this corresponds to the main() 
  function, for a spawned thread, it corresponds to the thread function.

%frame getNextFrame(%frame f);
  Return the previous frame on the stack.  This function is undefined if f
  satisfies the predicate isFirstFrame(f).

Label *getFrameLabel(%frame f);
  If a label was associated with f (as discussed below), this function returns
  it.  Otherwise, it returns a null pointer.

doNonLocalBranch(Label *L);
  At this point, it is not clear whether this should be a function or 
  intrinsic.  It should probably be an intrinsic in LLVM, but we'll deal with
  this issue later.


Here is a motivating example that illustrates how these facilities could be
used to implement the C++ exception model:

void TestFunction(...) {
  A a; B b;
  foo();        // Any function call may throw
  bar();
  C c;

  try {
    D d;
    baz();
  } catch (int) {
    ...int Stuff...
    // execution continues after the try block: the exception is consumed
  } catch (double) {
    ...double stuff...
   throw;            // Exception is propogated
  }
}

This function would compile to approximately the following code (heavy 
pseudo code follows):

Func:
  %a = alloca A
  A::A(%a)        // These ctors & dtors could throw, but we ignore this 
  %b = alloca B   // minor detail for this example
  B::B(%b)

  call foo() with fooCleanup // An exception in foo is propogated to fooCleanup
  call bar() with barCleanup // An exception in bar is propogated to barCleanup

  %c = alloca C
  C::C(c)
  %d = alloca D
  D::D(d)
  call baz() with bazCleanup // An exception in baz is propogated to bazCleanup
  d->~D();
EndTry:                   // This label corresponds to the end of the try block
  c->~C()       // These could also throw, these are also ignored
  b->~B()
  a->~A()
  return

Note that this is a very straight forward and literal translation: exactly
what we want for zero cost (when unused) exception handling.  Especially on
platforms with many registers (ie, the IA64) setjmp/longjmp style exception
handling is *very* impractical.  Also, the "with" clauses describe the 
control flow paths explicitly so that analysis is not adversly effected.

The foo/barCleanup labels are implemented as:

TryCleanup:          // Executed if an exception escapes the try block  
  c->~C()
barCleanup:          // Executed if an exception escapes from bar()
  // fall through
fooCleanup:          // Executed if an exception escapes from foo()
  b->~B()
  a->~A()
  Exception *E = getThreadLocalException()
  call throw(E)      // Implemented by the C++ runtime, described below

Which does the work one would expect.  getThreadLocalException is a function
implemented by the C++ support library.  It returns the current exception 
object for the current thread.  Note that we do not attempt to recycle the 
shutdown code from before, because performance of the mainline code is 
critically important.  Also, obviously fooCleanup and barCleanup may be 
merged and one of them eliminated.  This just shows how the code generator 
would most likely emit code.

The bazCleanup label is more interesting.  Because the exception may be caught
by the try block, we must dispatch to its handler... but it does not exist
on the call stack (it does not have a VM Call->Label mapping installed), so 
we must dispatch statically with a goto.  The bazHandler thus appears as:

bazHandler:
  d->~D();    // destruct D as it goes out of scope when entering catch clauses
  goto TryHandler

In general, TryHandler is not the same as bazHandler, because multiple 
function calls could be made from the try block.  In this case, trivial 
optimization could merge the two basic blocks.  TryHandler is the code 
that actually determines the type of exception, based on the Exception object
itself.  For this discussion, assume that the exception object contains *at
least*:

1. A pointer to the RTTI info for the contained object
2. A pointer to the dtor for the contained object
3. The contained object itself

Note that it is necessary to maintain #1 & #2 in the exception object itself
because objects without virtual function tables may be thrown (as in this 
example).  Assuming this, TryHandler would look something like this:

TryHandler: 
  Exception *E = getThreadLocalException();
  switch (E->RTTIType) {
  case IntRTTIInfo:
    ...int Stuff...       // The action to perform from the catch block
    break;
  case DoubleRTTIInfo:
    ...double Stuff...    // The action to perform from the catch block
    goto TryCleanup       // This catch block rethrows the exception
    break;                // Redundant, eliminated by the optimizer
  default:
    goto TryCleanup       // Exception not caught, rethrow
  }

  // Exception was consumed
  if (E->dtor)
    E->dtor(E->object)    // Invoke the dtor on the object if it exists
  goto EndTry             // Continue mainline code...

And that is all there is to it.

The throw(E) function would then be implemented like this (which may be 
inlined into the caller through standard optimization):

function throw(Exception *E) {
  // Get the start of the stack trace...
  %frame %f = call getStackCurrentFrame()

  // Get the label information that corresponds to it
  label * %L = call getFrameLabel(%f)
  while (%L == 0 && !isFirstFrame(%f)) {
    // Loop until a cleanup handler is found
    %f = call getNextFrame(%f)
    %L = call getFrameLabel(%f)
  }

  if (%L != 0) {
    call setThreadLocalException(E)   // Allow handlers access to this...
    call doNonLocalBranch(%L)
  }
  // No handler found!
  call BlowUp()         // Ends up calling the terminate() method in use
}

That's a brief rundown of how C++ exception handling could be implemented in
llvm.  Java would be very similar, except it only uses destructors to unlock
synchronized blocks, not to destroy data.  Also, it uses two stack walks: a
nondestructive walk that builds a stack trace, then a destructive walk that
unwinds the stack as shown here. 

It would be trivial to get exception interoperability between C++ and Java.

