summaryrefslogtreecommitdiff
path: root/docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt
diff options
context:
space:
mode:
authormike-m <mikem.llvm@gmail.com>2010-05-06 23:45:43 +0000
committermike-m <mikem.llvm@gmail.com>2010-05-06 23:45:43 +0000
commit68cb31901c590cabceee6e6356d62c84142114cb (patch)
tree6444bddc975b662fbe47d63cd98a7b776a407c1a /docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt
parentc26ae5ab7e2d65b67c97524e66f50ce86445dec7 (diff)
downloadllvm-68cb31901c590cabceee6e6356d62c84142114cb.tar.gz
llvm-68cb31901c590cabceee6e6356d62c84142114cb.tar.bz2
llvm-68cb31901c590cabceee6e6356d62c84142114cb.tar.xz
Overhauled llvm/clang docs builds. Closes PR6613.
NOTE: 2nd part changeset for cfe trunk to follow. *** PRE-PATCH ISSUES ADDRESSED - clang api docs fail build from objdir - clang/llvm api docs collide in install PREFIX/ - clang/llvm main docs collide in install - clang/llvm main docs have full of hard coded destination assumptions and make use of absolute root in static html files; namely CommandGuide tools hard codes a website destination for cross references and some html cross references assume website root paths *** IMPROVEMENTS - bumped Doxygen from 1.4.x -> 1.6.3 - splits llvm/clang docs into 'main' and 'api' (doxygen) build trees - provide consistent, reliable doc builds for both main+api docs - support buid vs. install vs. website intentions - support objdir builds - document targets with 'make help' - correct clean and uninstall operations - use recursive dir delete only where absolutely necessary - added call function fn.RMRF which safeguards against botched 'rm -rf'; if any target (or any variable is evaluated) which attempts to remove any dirs which match a hard-coded 'safelist', a verbose error will be printed and make will error-stop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103213 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt')
-rw-r--r--docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt202
1 files changed, 0 insertions, 202 deletions
diff --git a/docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt b/docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt
deleted file mode 100644
index b546301d35..0000000000
--- a/docs/HistoricalNotes/2001-05-18-ExceptionHandling.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-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.
-