Conversation

Not sure I agree. Implementation-wise we put the fluid-bound handlers in their own lists (in TLS) but those are pushed/popped on boundaries of control frames that establish handlers; dunno how to avoid that coupling.
1
1
(The way "zero cost" handlers work is to emit a static handler map, and then drive a binary search for each pc through that map while unwinding; which could also be done here, but it's much heavier engineering since it'd involve bypassing LLVM's abstraction over DW2 unwind.)
1
2
If handlers are always addressed with a symbolic selector, you can have a struct of stacks, one per handler stack. No unwinding search necessary: just lookup the field in that struct by offset of that selector.
2
1
You can also switch the execution call/return stack independently from the handler stack, enabling you to run a handler without unwinding, and you can run with whicher handler stack is more appropriate.
1
I think we're speaking across purposes here, possibly about different stacks. I'm not talking about a control stack that a handler's code runs on; I am talking about just tracking the entry and exit of the main thread from program contexts in which any given handler is active.
1
Those entry/exit events push and pop a handler-pointer from a stack of handler-pointers. Those push/pops are considered too expensive to be in the main path, by some people. Same kind of folks who object to frame pointers existing at all.
2
1
Not saying this is especially reasonable, just saying when people talk up zero cost exceptions what they mean is this: literally no extra memory traffic for control flow entering or leaving a scope with a handler.
1
1
Is that a problem when try/catch/finally is pretty rare? Seems like unexpected and/or super common handler scopes from C++-style deconstructors and the like could be a problem.
2
There are some costs borne only at the site of the try/catch/finally and some others borne more systemically anywhere you might unwind through (emitting records full of dtors and/or landing pads; propagating the exception chain inwards if it's not mapped statically, as in SEH..)
2
1
Gotcha. I think more radical ideas are necessary to make this work. eg. I'm not a believer in automatic deconstructors or RIIA. I advocate for a hard line between acyclic value types that are safe to copy/alias, and manually-ished allocated/freed objects with reference identity.
2
2