Hi Duncan, I agree on the problem about linking with code - I actually do mention this in the paper. I propose adding a new calling convention called "excall". The central point of my paper is that only one parameter is needed as the return value (because of the use of the flag): the EAX register can safely be used for both the exception instance and the return value as these never appear simultaneously. That's the primary reason I use the Carry flag: To avoid allocating a global variable, a thread variable or an entire register solely for communicating exception conditions. Especially on register scarce architectures (vink, vink, Intel), it is important to avoid allocating an entire register for the purpose of signaling a single bit of information: 1 = an exception has occurred, 0 = no exception has occurred. Also, when you use a register, instead of a flag, to indicate the exception condition, the caller must explicitly check if the register is non-zero - this adds some overhead compared to the simple "jump-if-carry" instruction. Thanks for looking at my stuff and I can only say that I am HAPPY that this method is already known. I have not seen it implemented in any of the compilers I use, but the most important thing for me is just that the method is so great -- about four to five times faster than the traditional stack unwind method (try expands to setjmp, throw expands to longjmp) -- that I wanted to make sure that somebody somewhere knew about the method. I think I'll take my ideas to the OpenWatcom C++ mailing list as the OpenWatcom compiler uses setjmp()/longjmp() in its exception handling implementation (despite being one of the best compilers on the Intel platform). Cheers, Mikael Lyngvig> Hi Mikael, the idea of modifying functions so they return two parameters > (the usual one and an exception pointer or some kind of exception flag) > is well known. The LLVM vmkit project actually uses a variant of this: > rather than returning the exception pointer in a register, it sticks it > in a global thread local variable. > > I only took a quick look at your paper, but it seems to me that it has > a serious problem: you can't link C code using your exception handling > mechanism with C code compiled using another compiler, since the carry > flag may not be cleared on function return by the code compiled by the > other compiler. Perhaps you addressed this issue in your paper, as I > mentioned I only glanced at it. Vmkit doesn't suffer from this problem, > since only code that is aware of vmkit exceptions will store in the > global. > > Also, I don't see the point of the carry flag. Why don't you just > return the exception pointer in another register? If it is non-null > then an exception was raised. Are you trying to avoid register > pressure or save a cycle or two? > > Finally, you could implement this (or something close to it) pretty > easily in LLVM. Suppose you have a function "int f(params) {...}". > Rather than outputting this to LLVM IR as > define i32 @f(params) { ... } > you output it as > define {i32, i8*} @f(params) { ... } > The additional return value is the exception pointer, which callers > can then inspect to see whether an exception was raised. On x86-64 > codegen will return the i32 in RAX and the exception pointer in RDX. > > Ciao, > > Duncan. >
> Thanks for looking at my stuff and I can only say that I am HAPPY that > this method is already known. I have not seen it implemented in any of > the compilers I use, but the most important thing for me is just that the > method is so great -- about four to five times faster than the traditional > stack unwind method (try expands to setjmp, throw expands to longjmp) -- > that I wanted to make sure that somebody somewhere knew about the method. >C++ exception implementation are optimized for the case where no exception is throw (opposite to what is done in python or maybe in java). Because in C++ exception are exceptionnal and should not be thrown during a normal execution of a program (use return code in this case). At least this is what all the C++ guru preach (that I know of). I don't think your implementation can be faster than current zero cost exception model used currently (where metainformation is added somewhere for unwinding, but no other code is needed) in the case of no exception throw. And like I said, in the other case we don't care much about speed, since it is an exceptional occurrence. This is just the way I see it, but at least for C++, the current solution seems more appropriate. obviously, for language like python which use exception to exit loop, this isn't the same thinks at all. just my 2cents Cédric
Mikael Lyngvig wrote:> Hi Duncan, > > I agree on the problem about linking with code - I actually do mention > this in the paper. I propose adding a new calling convention called > "excall". >The problem is that you can't automatically determine from a function declaration whether it comes from "inside" (is exception-aware) or not. This means that you'd have to make the user explicitly declare one of them. This is either a nightmare for using libraries (modify all headers, or introduce an extern "C"-block-like feature as C++ has it, to wrap the header includes), or a nightmare for writing new code (every new function needs to have it, explicitly). Sebastian
On Fri, Sep 04, 2009 at 05:06:34PM +0200, Sebastian Redl wrote:> Mikael Lyngvig wrote: > The problem is that you can't automatically determine from a function > declaration whether it comes from "inside" (is exception-aware) or not.Just throwing the idea in the air: link time optimization of exception handling? :) -- Felipe.
Sebastian Redl wrote:> Mikael Lyngvig wrote: > >> Hi Duncan, >> >> I agree on the problem about linking with code - I actually do mention >> this in the paper. I propose adding a new calling convention called >> "excall". >> >> > The problem is that you can't automatically determine from a function > declaration whether it comes from "inside" (is exception-aware) or not. > This means that you'd have to make the user explicitly declare one of > them. This is either a nightmare for using libraries (modify all > headers, or introduce an extern "C"-block-like feature as C++ has it, to > wrap the header includes), or a nightmare for writing new code (every > new function needs to have it, explicitly). >You could use some form name mangling on all symbols which are exception aware. When there is a mismatch between callee and caller you will get a undefined symbol. You would then add thunks for these symbols (by having a tool which parse error messages from the linker or by modifying the linker to add them). When an exception aware function calls a non exception aware one the thunk should call the function, clear the flags and then return. When an non exception aware function calls a function which might throw the thunk should check for an exception. If there is a pending exception it should abort, otherwise it would just return. -- Richard Osborne | XMOS http://www.xmos.com
Apparently Analagous Threads
- [LLVMdev] An alternate implementation of exceptions
- [LLVMdev] An alternate implementation of exceptions
- [LLVMdev] An alternate implementation of exceptions
- [LLVMdev] [Fwd: Re: An alternate implementation of exceptions]
- [LLVMdev] Anybody translating the LLVM FAQ from HTML to Sphinx?