Whole document tree eh_alloc.ccGo 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 "bits/c++config.h" 00039 #include "bits/gthr.h" 00040 00041 using namespace __cxxabiv1; 00042 00043 00044 // ??? How to control these parameters. 00045 00046 // Guess from the size of basic types how large a buffer is reasonable. 00047 // Note that the basic c++ exception header has 13 pointers and 2 ints, 00048 // so on a system with PSImode pointers we're talking about 56 bytes 00049 // just for overhead. 00050 00051 #if INT_MAX == 32767 00052 # define EMERGENCY_OBJ_SIZE 128 00053 # define EMERGENCY_OBJ_COUNT 16 00054 #elif LONG_MAX == 2147483647 00055 # define EMERGENCY_OBJ_SIZE 512 00056 # define EMERGENCY_OBJ_COUNT 32 00057 #else 00058 # define EMERGENCY_OBJ_SIZE 1024 00059 # define EMERGENCY_OBJ_COUNT 64 00060 #endif 00061 00062 #ifndef __GTHREADS 00063 # undef EMERGENCY_OBJ_COUNT 00064 # define EMERGENCY_OBJ_COUNT 4 00065 #endif 00066 00067 #if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32 00068 typedef unsigned int bitmask_type; 00069 #else 00070 typedef unsigned long bitmask_type; 00071 #endif 00072 00073 00074 typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned)); 00075 static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT]; 00076 static bitmask_type emergency_used; 00077 00078 00079 #ifdef __GTHREADS 00080 #ifdef __GTHREAD_MUTEX_INIT 00081 static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT; 00082 #else 00083 static __gthread_mutex_t emergency_mutex; 00084 #endif 00085 00086 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION 00087 static void 00088 emergency_mutex_init () 00089 { 00090 __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex); 00091 } 00092 #endif 00093 #endif 00094 00095 00096 extern "C" void * 00097 __cxa_allocate_exception(std::size_t thrown_size) 00098 { 00099 void *ret; 00100 00101 thrown_size += sizeof (__cxa_exception); 00102 ret = std::malloc (thrown_size); 00103 00104 if (! ret) 00105 { 00106 #ifdef __GTHREADS 00107 #ifdef __GTHREAD_MUTEX_INIT_FUNCTION 00108 static __gthread_once_t once = __GTHREAD_ONCE_INIT; 00109 __gthread_once (&once, emergency_mutex_init); 00110 #endif 00111 __gthread_mutex_lock (&emergency_mutex); 00112 #endif 00113 00114 bitmask_type used = emergency_used; 00115 unsigned int which = 0; 00116 00117 if (thrown_size > EMERGENCY_OBJ_SIZE) 00118 goto failed; 00119 while (used & 1) 00120 { 00121 used >>= 1; 00122 if (++which >= EMERGENCY_OBJ_COUNT) 00123 goto failed; 00124 } 00125 00126 emergency_used |= (bitmask_type)1 << which; 00127 ret = &emergency_buffer[which][0]; 00128 00129 failed:; 00130 #ifdef __GTHREADS 00131 __gthread_mutex_unlock (&emergency_mutex); 00132 #endif 00133 if (!ret) 00134 std::terminate (); 00135 } 00136 00137 std::memset (ret, 0, sizeof (__cxa_exception)); 00138 00139 return (void *)((char *)ret + sizeof (__cxa_exception)); 00140 } 00141 00142 00143 extern "C" void 00144 __cxa_free_exception(void *vptr) 00145 { 00146 char *ptr = (char *) vptr; 00147 if (ptr >= &emergency_buffer[0][0] 00148 && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer)) 00149 { 00150 unsigned int which 00151 = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE; 00152 00153 #ifdef __GTHREADS 00154 __gthread_mutex_lock (&emergency_mutex); 00155 emergency_used &= ~((bitmask_type)1 << which); 00156 __gthread_mutex_unlock (&emergency_mutex); 00157 #else 00158 emergency_used &= ~((bitmask_type)1 << which); 00159 #endif 00160 } 00161 else 00162 std::free (ptr - sizeof (__cxa_exception)); 00163 } Generated on Mon Apr 8 03:11:24 2002 for libstdc++-v3 Source by ![]() |