]>
Commit | Line | Data |
---|---|---|
4c0315d0 | 1 | // -*- C++ -*- Exception handling routines for Transactional Memory. |
f1717362 | 2 | // Copyright (C) 2009-2016 Free Software Foundation, Inc. |
4c0315d0 | 3 | // |
4 | // This file is part of GCC. | |
5 | // | |
6 | // GCC is free software; you can redistribute it and/or modify | |
7 | // it under the terms of the GNU General Public License as published by | |
8 | // the Free Software Foundation; either version 3, or (at your option) | |
9 | // any later version. | |
10 | // | |
11 | // GCC is distributed in the hope that it will be useful, | |
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | // GNU General Public License for more details. | |
15 | // | |
16 | // Under Section 7 of GPL version 3, you are granted additional | |
17 | // permissions described in the GCC Runtime Library Exception, version | |
18 | // 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | // You should have received a copy of the GNU General Public License and | |
21 | // a copy of the GCC Runtime Library Exception along with this program; | |
22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | // <http://www.gnu.org/licenses/>. | |
24 | ||
25 | #include <cstdlib> | |
26 | #include "unwind-cxx.h" | |
27 | ||
28 | using namespace __cxxabiv1; | |
29 | ||
30 | // Free one C++ exception. | |
31 | ||
32 | static void | |
33 | free_any_cxa_exception (_Unwind_Exception *eo) | |
34 | { | |
35 | __cxa_refcounted_exception *h | |
36 | = __get_refcounted_exception_header_from_ue (eo); | |
37 | ||
38 | if (__is_dependent_exception (eo->exception_class)) | |
39 | { | |
40 | __cxa_dependent_exception *dep | |
41 | = __get_dependent_exception_from_ue (eo); | |
42 | ||
43 | h = __get_refcounted_exception_header_from_obj (dep->primaryException); | |
44 | ||
45 | __cxa_free_dependent_exception (dep); | |
46 | } | |
47 | ||
7f81a670 | 48 | #if __GCC_ATOMIC_INT_LOCK_FREE > 1 |
f06b9073 | 49 | if (__atomic_sub_fetch (&h->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) |
09166845 | 50 | #endif |
4c0315d0 | 51 | __cxa_free_exception (h + 1); |
52 | } | |
53 | ||
54 | // Cleanup exception handling state while rolling back state for | |
55 | // a software transactional memory transaction. | |
56 | // | |
57 | // UNTHROWN_OBJ is non-null if we've called __cxa_allocate_exception | |
58 | // but not yet called __cxa_throw for it. | |
59 | // | |
60 | // CLEANUP_EXC is non-null if we're currently processing a cleanup | |
61 | // along an exception path, but we've not caught the exception yet. | |
62 | // | |
63 | // CAUGHT_COUNT is the nesting depth of __cxa_begin_catch within | |
64 | // the transaction; undo as if calling __cxa_end_catch that many times. | |
65 | ||
66 | extern "C" void | |
67 | __cxxabiv1::__cxa_tm_cleanup (void *unthrown_obj, | |
68 | void *cleanup_exc, | |
69 | unsigned int caught_count) throw() | |
70 | { | |
71 | __cxa_eh_globals *globals = __cxa_get_globals_fast (); | |
72 | ||
73 | // Handle a C++ exception not yet thrown. | |
74 | if (unthrown_obj) | |
75 | { | |
76 | globals->uncaughtExceptions -= 1; | |
77 | __cxa_free_exception (unthrown_obj); | |
78 | } | |
79 | ||
80 | // Handle an exception not yet caught ie. processing a cleanup | |
81 | // in between the throw and the catch. | |
82 | if (cleanup_exc) | |
83 | { | |
84 | _Unwind_Exception *eo | |
85 | = reinterpret_cast <_Unwind_Exception *>(cleanup_exc); | |
86 | if (__is_gxx_exception_class (eo->exception_class)) | |
87 | free_any_cxa_exception (eo); | |
88 | else | |
89 | _Unwind_DeleteException (eo); | |
90 | } | |
91 | ||
92 | // Do __cxa_end_catch caught_count times, but don't bother running | |
93 | // the destructors for the objects involved. All of that is being | |
94 | // undone by the transaction restart. | |
95 | if (caught_count > 0) | |
96 | { | |
97 | __cxa_exception *h = globals->caughtExceptions; | |
98 | ||
99 | // Rethrown foreign exceptions are removed from the stack immediately. | |
100 | // We would have freed this exception via THIS_EXC above. | |
101 | if (h == NULL) | |
102 | return; | |
103 | ||
104 | do | |
105 | { | |
106 | __cxa_exception *next; | |
107 | _Unwind_Exception *eo = &h->unwindHeader; | |
108 | ||
109 | if (__is_gxx_exception_class (eo->exception_class)) | |
110 | { | |
111 | next = h->nextException; | |
112 | free_any_cxa_exception (eo); | |
113 | } | |
114 | else | |
115 | { | |
116 | _Unwind_DeleteException (eo); | |
117 | next = 0; | |
118 | } | |
119 | ||
120 | h = next; | |
121 | } | |
122 | while (--caught_count); | |
123 | ||
124 | globals->caughtExceptions = h; | |
125 | } | |
126 | } |