[cfe-commits] [libcxxabi] r146172 - in /libcxxabi/trunk: src/cxa_exception.cpp src/cxa_exception.hpp www/spec.html
Howard Hinnant
hhinnant at apple.com
Thu Dec 8 11:35:19 PST 2011
Author: hhinnant
Date: Thu Dec 8 13:35:18 2011
New Revision: 146172
URL: http://llvm.org/viewvc/llvm-project?rev=146172&view=rev
Log:
Modified __cxa_end_catch to handle dependent exceptions.
Modified:
libcxxabi/trunk/src/cxa_exception.cpp
libcxxabi/trunk/src/cxa_exception.hpp
libcxxabi/trunk/www/spec.html
Modified: libcxxabi/trunk/src/cxa_exception.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.cpp?rev=146172&r1=146171&r2=146172&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.cpp (original)
+++ libcxxabi/trunk/src/cxa_exception.cpp Thu Dec 8 13:35:18 2011
@@ -65,14 +65,14 @@
return (unwind->exception_class & 0xFF) == 0x01;
}
-// TODO: This needs to be atomic
-static int incrementHandlerCount(__cxa_exception *exception) throw() {
- return ++exception->handlerCount;
+// This does not need to be atomic
+static inline int incrementHandlerCount(__cxa_exception *exception) throw() {
+ return ++exception->handlerCount;
}
-// TODO: This needs to be atomic
-static int decrementHandlerCount(__cxa_exception *exception) throw() {
- return --exception->handlerCount;
+// This does not need to be atomic
+static inline int decrementHandlerCount(__cxa_exception *exception) throw() {
+ return --exception->handlerCount;
}
#include "fallback_malloc.cpp"
@@ -192,7 +192,7 @@
__cxa_throw(void * thrown_exception, std::type_info * tinfo, void (*dest)(void *)) {
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *exception = exception_from_thrown_object(thrown_exception);
-
+
exception->unexpectedHandler = std::get_unexpected();
exception->terminateHandler = std::get_terminate();
exception->exceptionType = tinfo;
@@ -202,8 +202,11 @@
globals->uncaughtExceptions += 1; // Not atomically, since globals are thread-local
exception->unwindHeader.exception_cleanup = exception_cleanup_func;
+#if __arm__
+ _Unwind_SjLj_RaiseException(&exception->unwindHeader);
+#else
_Unwind_RaiseException(&exception->unwindHeader);
-
+#endif
// If we get here, some kind of unwinding error has occurred.
failed_throw(exception);
}
@@ -227,6 +230,8 @@
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *exception = exception_from_exception_object(exceptionObject);
+// TODO: Handle foreign exceptions? How?
+
// Increment the handler count, removing the flag about being rethrown
exception->handlerCount = exception->handlerCount < 0 ?
-exception->handlerCount + 1 : exception->handlerCount + 1;
@@ -249,28 +254,44 @@
This routine:
* Locates the most recently caught exception and decrements its handler count.
* Removes the exception from the caught exception stack, if the handler count goes to zero.
-* Destroys the exception if the handler count goes to zero, and the exception was not re-thrown by throw.
+* If the handler count goes down to zero, and the exception was not re-thrown
+ by throw, it locates the primary exception (which may be the same as the one
+ it's handling) and decrements its reference count. If that reference count
+ goes to zero, the function destroys the exception. In any case, if the current
+ exception is a dependent exception, it destroys that.
*/
void __cxa_end_catch() {
- __cxa_eh_globals *globals = __cxa_get_globals();
+ __cxa_eh_globals *globals = __cxa_get_globals_fast(); // __cxa_get_globals called in __cxa_begin_catch
__cxa_exception *current_exception = globals->caughtExceptions;
if (NULL != current_exception) {
if (current_exception->handlerCount < 0) {
// The exception has been rethrown
if (0 == incrementHandlerCount(current_exception)) {
+ // Remove from the chain of uncaught exceptions
globals->caughtExceptions = current_exception->nextException;
- // Howard says: If the exception has been rethrown, don't destroy.
- }
+ // but don't destroy
+ }
}
- else {
+ else { // The exception has not been rethrown
if (0 == decrementHandlerCount(current_exception)) {
- // Remove from the chain of uncaught exceptions
+ // Remove from the chain of uncaught exceptions
globals->caughtExceptions = current_exception->nextException;
- if (!isDependentException(¤t_exception->unwindHeader))
- _Unwind_DeleteException(¤t_exception->unwindHeader);
- else {
- // TODO: deal with a dependent exception
+ if (isDependentException(¤t_exception->unwindHeader)) {
+ // Reset current_exception to primaryException and deallocate the dependent exception
+ __cxa_dependent_exception* deh =
+ reinterpret_cast<__cxa_dependent_exception*>(current_exception + 1) - 1;
+ current_exception = static_cast<__cxa_exception*>(deh->primaryException) - 1;
+ __cxa_free_dependent_exception(deh);
+ }
+ // Destroy the primary exception only if its referenceCount goes to 0
+ // (this decrement must be atomic)
+ if (__sync_sub_and_fetch(¤t_exception->referenceCount, size_t(1)) == 0)
+ {
+ void* thrown_object = thrown_object_from_exception(current_exception);
+ if (NULL != current_exception->exceptionDestructor)
+ current_exception->exceptionDestructor(thrown_object);
+ __cxa_free_exception(thrown_object);
}
}
}
@@ -306,7 +327,7 @@
std::terminate ();
// Mark the exception as being rethrown
- exception->handlerCount = -exception->handlerCount ; // TODO: Atomic
+ exception->handlerCount = -exception->handlerCount ; // TODO: Atomic
#if __arm__
(void) _Unwind_SjLj_Resume_or_Rethrow(&exception->unwindHeader);
Modified: libcxxabi/trunk/src/cxa_exception.hpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/cxa_exception.hpp?rev=146172&r1=146171&r2=146172&view=diff
==============================================================================
--- libcxxabi/trunk/src/cxa_exception.hpp (original)
+++ libcxxabi/trunk/src/cxa_exception.hpp Thu Dec 8 13:35:18 2011
@@ -56,6 +56,8 @@
_Unwind_Exception unwindHeader;
};
+
+// http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
struct __cxa_dependent_exception {
#if __LP64__
Modified: libcxxabi/trunk/www/spec.html
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/www/spec.html?rev=146172&r1=146171&r2=146172&view=diff
==============================================================================
--- libcxxabi/trunk/www/spec.html (original)
+++ libcxxabi/trunk/www/spec.html Thu Dec 8 13:35:18 2011
@@ -114,7 +114,7 @@
</td>
<td>✓</td>
<td>✓</td>
-<td></td>
+<td>✓</td>
</tr>
<tr>
More information about the cfe-commits
mailing list