[swift-evolution] ABI of throwing

Chris Lattner clattner at apple.com
Sun Aug 7 23:36:36 CDT 2016


On Aug 6, 2016, at 7:25 PM, Félix Cloutier via swift-evolution <swift-evolution at swift.org> wrote:
> This means that call sites for throwing functions must always check if an exception occurred. This makes it essentially equivalent to returning an error code in addition to the function's actual return type.

Right.

> On the other hand, there are exception handling mechanisms where the execution time cost in the success case is zero, and the error case is expensive. When you throw, the runtime walks through the return addresses on the stack to find out if there's an associated catch block that can handle the current exception. Apple uses this mechanism <https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#id29> (with the Itanium C++ ABI) for C++ and Objective-C exceptions, at least on x86_64.
> 
> Other compiler engineers, like Microsoft's Joe Duffy <http://joeduffyblog.com/2016/02/07/the-error-model/>, have determined that there actually is a non-trivial cost associated to branching for error codes. In exchange for faster error cases, you get slower success cases. This is mildly unfortunate for throwing functions that overwhelmingly succeed.

Well sure.  However, if you’re comparing against Objective-C and C++, you have to account for an important structural difference.  The compiler for those languages has to assume that *any function* (to a first order approximation) can throw.  In Swift, the language strongly disincentives developers from marking stuff “throw” that can not actually throw (by requiring calls to be marked with ‘try’).

“Zero cost” EH is also *extremely* expensive in the case where an error is actually throw in normal use cases.  This makes it completely inappropriate for use in APIs where errors are expected in edge cases (e.g. file not found errors).

> I don't really know what to expect in terms of discussion, especially since it may boil down to "we're experts in this fields and you're just peasants”

I’m not sure why you think the Swift team would say something that derogatory.  I hope there is no specific action that has led to this belief. If there is, then please let me know.

> or "the cost of changing this isn't worth the benefit". Still, I'd like some more insight into why Swift exceptions don't use the same mechanism as C++ exceptions and Objective-C exceptions. The error handling rationale document is very terse <https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst#id62> on the implementation design, especially given the length of the rest of the document.

This is simply because it is of interest to fewer people, and no document can anticipate the interest of all readers.  Ask specific questions and we’ll provide specific answers.

>  However, as linked above, someone did for Microsoft platforms (for Microsoft-platform-style errors) and found that there is an impact. 

C++ and Swift are completely different languages in this respect, so the analysis doesn’t translate over.

> Throwing and unwind tables are all over the place in a lot of languages that have exceptions (C++, Java, C#).

Yes, and many C++ projects build with -fno-exceptions because of the huge code and metadata bloat associated with them.  This is one of many mistakes in C++/Java/etc that we do not want to repeat with Swift.  Additionally, unlike Java, Swift doesn’t generally have the benefit of a JIT compiler that can lazily create these structures on demand.

-Chris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160807/e44fd6df/attachment.html>


More information about the swift-evolution mailing list