Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

eh_alloc.cc

Go to the documentation of this file.
00001 // -*- C++ -*- Allocate exception objects.
00002 // Copyright (C) 2001 Free Software Foundation, Inc.
00003 //
00004 // This file is part of GNU CC.
00005 //
00006 // GNU CC is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation; either version 2, or (at your option)
00009 // any later version.
00010 //
00011 // GNU CC is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with GNU CC; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 59 Temple Place - Suite 330,
00019 // Boston, MA 02111-1307, USA.
00020 
00021 // As a special exception, you may use this file as part of a free software
00022 // library without restriction.  Specifically, if other files instantiate
00023 // templates or use macros or inline functions from this file, or you compile
00024 // this file and link it with other files to produce an executable, this
00025 // file does not by itself cause the resulting executable to be covered by
00026 // the GNU General Public License.  This exception does not however
00027 // invalidate any other reasons why the executable file might be covered by
00028 // the GNU General Public License.
00029 
00030 // This is derived from the C++ ABI for IA-64.  Where we diverge
00031 // for cross-architecture compatibility are noted with "@@@".
00032 
00033 #include <exception>
00034 #include <cstdlib>
00035 #include <cstring>
00036 #include <limits.h>
00037 #include "unwind-cxx.h"
00038 #include "gthr.h"
00039 
00040 using namespace __cxxabiv1;
00041 
00042 
00043 // ??? How to control these parameters.
00044 
00045 // Guess from the size of basic types how large a buffer is reasonable.
00046 // Note that the basic c++ exception header has 13 pointers and 2 ints,
00047 // so on a system with PSImode pointers we're talking about 56 bytes
00048 // just for overhead.
00049 
00050 #if INT_MAX == 32767
00051 # define EMERGENCY_OBJ_SIZE 128
00052 # define EMERGENCY_OBJ_COUNT    16
00053 #elif LONG_MAX == 2147483647
00054 # define EMERGENCY_OBJ_SIZE 512
00055 # define EMERGENCY_OBJ_COUNT    32
00056 #else
00057 # define EMERGENCY_OBJ_SIZE 1024
00058 # define EMERGENCY_OBJ_COUNT    64
00059 #endif
00060 
00061 #ifndef __GTHREADS
00062 # undef EMERGENCY_OBJ_COUNT
00063 # define EMERGENCY_OBJ_COUNT    4
00064 #endif
00065 
00066 #if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
00067 typedef unsigned int bitmask_type;
00068 #else
00069 typedef unsigned long bitmask_type;
00070 #endif
00071 
00072 
00073 typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
00074 static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
00075 static bitmask_type emergency_used;
00076 
00077 
00078 #ifdef __GTHREADS
00079 #ifdef __GTHREAD_MUTEX_INIT
00080 static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT;
00081 #else 
00082 static __gthread_mutex_t emergency_mutex;
00083 #endif
00084 
00085 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
00086 static void
00087 emergency_mutex_init ()
00088 {
00089   __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex);
00090 }
00091 #endif
00092 #endif
00093 
00094 
00095 extern "C" void *
00096 __cxa_allocate_exception(std::size_t thrown_size)
00097 {
00098   void *ret;
00099 
00100   thrown_size += sizeof (__cxa_exception);
00101   ret = malloc (thrown_size);
00102 
00103   if (! ret)
00104     {
00105 #ifdef __GTHREADS
00106 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION
00107       static __gthread_once_t once = __GTHREAD_ONCE_INIT;
00108       __gthread_once (&once, emergency_mutex_init);
00109 #endif
00110       __gthread_mutex_lock (&emergency_mutex);
00111 #endif
00112 
00113       bitmask_type used = emergency_used;
00114       unsigned int which = 0;
00115 
00116       if (thrown_size > EMERGENCY_OBJ_SIZE)
00117     goto failed;
00118       while (used & 1)
00119     {
00120       used >>= 1;
00121       if (++which >= EMERGENCY_OBJ_COUNT)
00122         goto failed;
00123     }
00124 
00125       emergency_used |= (bitmask_type)1 << which;
00126       ret = &emergency_buffer[which][0];
00127 
00128     failed:;
00129 #ifdef __GTHREADS
00130       __gthread_mutex_unlock (&emergency_mutex);
00131 #endif
00132       if (!ret)
00133     std::terminate ();
00134     }
00135 
00136   memset (ret, 0, sizeof (__cxa_exception));
00137 
00138   return (void *)((char *)ret + sizeof (__cxa_exception));
00139 }
00140 
00141 
00142 extern "C" void
00143 __cxa_free_exception(void *vptr)
00144 {
00145   char *ptr = (char *) vptr;
00146   if (ptr >= &emergency_buffer[0][0]
00147       && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
00148     {
00149       unsigned int which
00150     = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE;
00151 
00152 #ifdef __GTHREADS
00153       __gthread_mutex_lock (&emergency_mutex);
00154       emergency_used &= ~((bitmask_type)1 << which);
00155       __gthread_mutex_unlock (&emergency_mutex);
00156 #else
00157       emergency_used &= ~((bitmask_type)1 << which);
00158 #endif
00159     }
00160   else
00161     free (ptr - sizeof (__cxa_exception));
00162 }

Generated at Tue May 1 16:28:37 2001 for libstdc++-v3 by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001