On Mon, Jul 20, 2009 at 10:09 AM, Mark Shannon<marks at dcs.gla.ac.uk> wrote:> Andrew Haley wrote: > If you can make your point without any references to any C/C++ specific > features it might be more convincing ;) >I did. Recall my mention of java/c#/ruby/python's finally/ensure blocks, or C#'s using blocks. For proper implementation, these need multi-level unwinds, as they specify that some code must run, even if an exception would bail-out.> I take it you have never used Python ;) > (Python uses exceptions to terminate loops, so it helps if they aren't > too slow)I have used python, and it is slow (sorry). In fact, python Exceptions are implemented in python as a second return value, thus EVERY function, even those which don't throw exceptions, must pay the price. And just because the python community does it, doesn't mean it's good programming practice.>Please try and get out of the C++ mindset, llvm may be implemented *in* >C++, but its not implemented just *for* C++ (at least I hope it isn't).That is exactly my argument. Multi-level unwinds are required by MANY languages. -- Nick Johnson
Nick Johnson wrote:> On Mon, Jul 20, 2009 at 10:09 AM, Mark Shannon<marks at dcs.gla.ac.uk> wrote: >> Andrew Haley wrote: >> If you can make your point without any references to any C/C++ specific >> features it might be more convincing ;) >> > > I did. Recall my mention of java/c#/ruby/python's finally/ensureThe finally block is just a bit of syntactic sugar on a try/catch block: try: do something ex = NULL goto _final catch: ex = caught exception do something else _final: do something important if ex: rethrow ex> blocks, or C#'s using blocks. For proper implementation, these need > multi-level unwinds, as they specify that some code must run, even if > an exception would bail-out.You are confusing stopping the unwinding at *some* levels or at *all* levels. Eg. invoke call call invoke call call unwind Requires a two unwinding steps for Java/Python and six steps for C++. Only languages with stack-allocated objects must stop unwinding for calls.> >> I take it you have never used Python ;) >> (Python uses exceptions to terminate loops, so it helps if they aren't >> too slow) > > I have used python, and it is slow (sorry). In fact, pythonPython: write program 1 day, run program 10mins = 1day + 10mins C++: write program 1 month, run program 30 seconds = 1month + 30 secs It depends on how you look at it, but we are getting off topic here :)> Exceptions are implemented in python as a second return value, thusOnly in one particular Python implementation, there are several. Its not in the language spec.> EVERY function, even those which don't throw exceptions, must pay the > price. And just because the python community does it, doesn't mean > it's good programming practice.The same could be said of C++. Both languages have their place, and llvm should support compilers for both (and lots of other languages as well).> >> Please try and get out of the C++ mindset, llvm may be implemented *in* >> C++, but its not implemented just *for* C++ (at least I hope it isn't). > > That is exactly my argument. Multi-level unwinds are required by MANY > languages. >Not in the same way as C++, see above.
On Mon, Jul 20, 2009 at 10:33 AM, Mark Shannon<marks at dcs.gla.ac.uk> wrote:> You are confusing stopping the unwinding at *some* levels or at *all* > levels. > Eg. > invoke > call > call > invoke > call > call > unwind > > Requires a two unwinding steps for Java/Python and six steps for C++. > Only languages with stack-allocated objects must stop unwinding for calls.C++ doesn't need you to stop unwinding at every level. Only at levels where stack-allocated objects with non-trivial destructors exist. At those levels, the code generator can turn all calls into invokes. Other levels can be skipped, since stack-allocated objects without non-trivial destructors can simply be abandoned as the stack pointer is bumped past them. So a function with stack-allocated objects having non-trivial destructors is pretty much the equivalent of a function with a finalizer, and can be code-generated as such using invokes instead of calls. Calls can still be skipped. The difference is that many C++ programs will tend to wind up with more invokes.> >> >>> I take it you have never used Python ;) >>> (Python uses exceptions to terminate loops, so it helps if they aren't >>> too slow) >> >> I have used python, and it is slow (sorry). In fact, python > > Python: write program 1 day, run program 10mins = 1day + 10mins > C++: write program 1 month, run program 30 seconds = 1month + 30 secs > It depends on how you look at it, but we are getting off topic here :) > >> Exceptions are implemented in python as a second return value, thus > Only in one particular Python implementation, there are several. > Its not in the language spec. > >> EVERY function, even those which don't throw exceptions, must pay the >> price. And just because the python community does it, doesn't mean >> it's good programming practice. > The same could be said of C++. Both languages have their place, and llvm > should support compilers for both (and lots of other languages as well). >> >>> Please try and get out of the C++ mindset, llvm may be implemented *in* >>> C++, but its not implemented just *for* C++ (at least I hope it isn't). >> >> That is exactly my argument. Multi-level unwinds are required by MANY >> languages. >> > Not in the same way as C++, see above. > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Hi,> Python: write program 1 day, run program 10mins = 1day + 10mins > C++: write program 1 month, run program 30 seconds = 1month + 30 secs > It depends on how you look at it, but we are getting off topic here :) >> > Exceptions are implemented in python as a second return value, thus > Only in one particular Python implementation, there are several. > Its not in the language spec. > > > EVERY function, even those which don't throw exceptions, must pay the > > price. And just because the python community does it, doesn't mean > > it's good programming practice. > The same could be said of C++. Both languages have their place, and llvm > should support compilers for both (and lots of other languages as well). > > > >> Please try and get out of the C++ mindset, llvm may be implemented *in* > >> C++, but its not implemented just *for* C++ (at least I hope it isn't). > > > > That is exactly my argument. Multi-level unwinds are required by MANY > > languages. > > > Not in the same way as C++, see above. > >Why this crusade against semantics you associate with C++? Is there something conceptually impure about these semantics? Kind regards, Maurice> > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090720/0a8f25f2/attachment.html>
Hi Mark,> You are confusing stopping the unwinding at *some* levels or at *all* > levels. > Eg. > invoke > call > call > invoke > call > call > unwindthe dwarf unwinder only stops and runs user code at the invokes. It does restore registers and so forth at every stack frame. This is extra work done at unwind time that reduces the cost of making invoke calls by avoiding the need to save a bunch of context. Ciao, Duncan.
On Mon, Jul 20, 2009 at 7:43 AM, Nick Johnson<nicholas.paul.johnson at gmail.com> wrote:> On Mon, Jul 20, 2009 at 10:09 AM, Mark Shannon<marks at dcs.gla.ac.uk> wrote: >> Andrew Haley wrote: >> If you can make your point without any references to any C/C++ specific >> features it might be more convincing ;) >> > > I did. Recall my mention of java/c#/ruby/python's finally/ensure > blocks, or C#'s using blocks. For proper implementation, these need > multi-level unwinds, as they specify that some code must run, even if > an exception would bail-out. > >> I take it you have never used Python ;) >> (Python uses exceptions to terminate loops, so it helps if they aren't >> too slow) > > I have used python, and it is slow (sorry). In fact, python > Exceptions are implemented in python as a second return value, thus > EVERY function, even those which don't throw exceptions, must pay the > price. And just because the python community does it, doesn't mean > it's good programming practice.:) Working on Unladen Swallow, we've considered whether to try to port Python to use Dwarf unwinding. It's a fairly simple tradeoff: with return-value-exceptions you get a small cost in both time (a predictable branch) and code size at each call site, whether or not the call site is inside a try, but you get pretty cheap exception throwing and propagation. With dwarf-exceptions, you have a small space cost at each invoke (for the dwarf metadata), no time cost at calls that don't throw, but fairly expensive exceptions when you do throw them. Because Python throws exceptions for ending loops and garbage-collecting generators, we expect return-value-exceptions to be cheaper overall. In languages that throw exceptions more rarely (just about everyone), dwarf-exceptions should be cheaper. Dwarf-exceptions will still be worth investigating for Python eventually; we're just not prioritizing it. Anyone who wants us to prioritize it higher should bring data. :) IronPython's and Jython's experiences are interesting too. IronPython has had big problems with the cost of exceptions on the .NET platform. Jython has _not_ had problems in the JVM, which indicates that the two big virtual machines have made different tradeoffs for this. That would make me very hesitant to say that either option is obviously wrong. Jeffrey
Jeffrey Yasskin wrote:> On Mon, Jul 20, 2009 at 7:43 AM, Nick > Johnson<nicholas.paul.johnson at gmail.com> wrote: >> On Mon, Jul 20, 2009 at 10:09 AM, Mark Shannon<marks at dcs.gla.ac.uk> wrote: >>> Andrew Haley wrote: >>> If you can make your point without any references to any C/C++ specific >>> features it might be more convincing ;) >>> >> I did. Recall my mention of java/c#/ruby/python's finally/ensure >> blocks, or C#'s using blocks. For proper implementation, these need >> multi-level unwinds, as they specify that some code must run, even if >> an exception would bail-out. >> >>> I take it you have never used Python ;) >>> (Python uses exceptions to terminate loops, so it helps if they aren't >>> too slow) >> I have used python, and it is slow (sorry). In fact, python >> Exceptions are implemented in python as a second return value, thus >> EVERY function, even those which don't throw exceptions, must pay the >> price. And just because the python community does it, doesn't mean >> it's good programming practice. > > :) > > Working on Unladen Swallow, we've considered whether to try to port > Python to use Dwarf unwinding. It's a fairly simple tradeoff: with > return-value-exceptions you get a small cost in both time (a > predictable branch) and code size at each call site, whether or not > the call site is inside a try, but you get pretty cheap exception > throwing and propagation. With dwarf-exceptions, you have a small > space cost at each invoke (for the dwarf metadata), no time cost at > calls that don't throw, but fairly expensive exceptions when you do > throw them. Because Python throws exceptions for ending loops and > garbage-collecting generators, we expect return-value-exceptions to be > cheaper overall. In languages that throw exceptions more rarely (just > about everyone), dwarf-exceptions should be cheaper. Dwarf-exceptions > will still be worth investigating for Python eventually; we're just > not prioritizing it. Anyone who wants us to prioritize it higher > should bring data. :) > > IronPython's and Jython's experiences are interesting too. IronPython > has had big problems with the cost of exceptions on the .NET platform. > Jython has _not_ had problems in the JVM, which indicates that the two > big virtual machines have made different tradeoffs for this. That > would make me very hesitant to say that either option is obviously > wrong.The JVM is interesting because creating an exception in Java is expensive (generating the backtrace) but throwing one is quite cheep> > Jeffrey > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >