Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*- Exception handling routines for Transactional Memory.
  2. // Copyright (C) 2009-2015 Free Software Foundation, Inc.
  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.  
  48. #if __GCC_ATOMIC_INT_LOCK_FREE > 1
  49.   if (__atomic_sub_fetch (&h->referenceCount, 1, __ATOMIC_ACQ_REL) == 0)
  50. #endif
  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. }
  127.