]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/libsupc++/eh_alloc.cc
invoke.texi: Replace "bugfix" with "bug fix" throughout.
[thirdparty/gcc.git] / libstdc++-v3 / libsupc++ / eh_alloc.cc
CommitLineData
52a11cbf 1// -*- C++ -*- Allocate exception objects.
656032b8
PC
2// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
3// Free Software Foundation, Inc.
52a11cbf 4//
cbecceb9 5// This file is part of GCC.
52a11cbf 6//
cbecceb9 7// GCC is free software; you can redistribute it and/or modify
52a11cbf
RH
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2, or (at your option)
10// any later version.
11//
cbecceb9 12// GCC is distributed in the hope that it will be useful,
52a11cbf
RH
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
cbecceb9 18// along with GCC; see the file COPYING. If not, write to
83f51799
KC
19// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20// Boston, MA 02110-1301, USA.
52a11cbf
RH
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction. Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License. This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31// This is derived from the C++ ABI for IA-64. Where we diverge
32// for cross-architecture compatibility are noted with "@@@".
33
b967bf25 34#include <bits/c++config.h>
52a11cbf 35#include <cstdlib>
4c24b21a 36#if _GLIBCXX_HOSTED
52a11cbf 37#include <cstring>
4c24b21a 38#endif
213c2316 39#include <climits>
93b85586 40#include <exception>
52a11cbf 41#include "unwind-cxx.h"
2e362c74 42#include <ext/concurrence.h>
52a11cbf 43
4c24b21a
MM
44#if _GLIBCXX_HOSTED
45using std::free;
46using std::malloc;
05a79eb6 47using std::memset;
4c24b21a 48#else
3cbc7af0
BK
49// In a freestanding environment, these functions may not be available
50// -- but for now, we assume that they are.
4c24b21a
MM
51extern "C" void *malloc (std::size_t);
52extern "C" void free(void *);
656032b8 53extern "C" void *memset (void *, int, std::size_t);
4c24b21a 54#endif
52a11cbf 55
4c24b21a 56using namespace __cxxabiv1;
52a11cbf
RH
57
58// ??? How to control these parameters.
59
60// Guess from the size of basic types how large a buffer is reasonable.
61// Note that the basic c++ exception header has 13 pointers and 2 ints,
62// so on a system with PSImode pointers we're talking about 56 bytes
63// just for overhead.
64
65#if INT_MAX == 32767
66# define EMERGENCY_OBJ_SIZE 128
67# define EMERGENCY_OBJ_COUNT 16
68#elif LONG_MAX == 2147483647
69# define EMERGENCY_OBJ_SIZE 512
70# define EMERGENCY_OBJ_COUNT 32
71#else
72# define EMERGENCY_OBJ_SIZE 1024
73# define EMERGENCY_OBJ_COUNT 64
74#endif
75
76#ifndef __GTHREADS
77# undef EMERGENCY_OBJ_COUNT
78# define EMERGENCY_OBJ_COUNT 4
79#endif
80
81#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
82typedef unsigned int bitmask_type;
83#else
84typedef unsigned long bitmask_type;
85#endif
86
87
88typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
89static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
90static bitmask_type emergency_used;
91
2e362c74 92namespace
52a11cbf 93{
2e362c74
BK
94 // A single mutex controlling emergency allocations.
95 __gnu_cxx::__mutex emergency_mutex;
52a11cbf 96}
52a11cbf
RH
97
98extern "C" void *
723acbd5 99__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) throw()
52a11cbf
RH
100{
101 void *ret;
102
103 thrown_size += sizeof (__cxa_exception);
4c24b21a 104 ret = malloc (thrown_size);
52a11cbf
RH
105
106 if (! ret)
107 {
2e362c74 108 __gnu_cxx::__scoped_lock sentry(emergency_mutex);
52a11cbf
RH
109
110 bitmask_type used = emergency_used;
111 unsigned int which = 0;
112
f847167e
NS
113 if (thrown_size > EMERGENCY_OBJ_SIZE)
114 goto failed;
52a11cbf
RH
115 while (used & 1)
116 {
117 used >>= 1;
118 if (++which >= EMERGENCY_OBJ_COUNT)
f847167e 119 goto failed;
52a11cbf
RH
120 }
121
122 emergency_used |= (bitmask_type)1 << which;
123 ret = &emergency_buffer[which][0];
124
f847167e 125 failed:;
2e362c74 126
f847167e
NS
127 if (!ret)
128 std::terminate ();
52a11cbf
RH
129 }
130
39609077
RH
131 // We have an uncaught exception as soon as we allocate memory. This
132 // yields uncaught_exception() true during the copy-constructor that
133 // initializes the exception object. See Issue 475.
134 __cxa_eh_globals *globals = __cxa_get_globals ();
135 globals->uncaughtExceptions += 1;
136
4c24b21a 137 memset (ret, 0, sizeof (__cxa_exception));
52a11cbf
RH
138
139 return (void *)((char *)ret + sizeof (__cxa_exception));
140}
141
142
143extern "C" void
723acbd5 144__cxxabiv1::__cxa_free_exception(void *vptr) throw()
52a11cbf
RH
145{
146 char *ptr = (char *) vptr;
147 if (ptr >= &emergency_buffer[0][0]
148 && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
149 {
2e362c74 150 const unsigned int which
52a11cbf
RH
151 = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE;
152
2e362c74 153 __gnu_cxx::__scoped_lock sentry(emergency_mutex);
52a11cbf 154 emergency_used &= ~((bitmask_type)1 << which);
52a11cbf
RH
155 }
156 else
4c24b21a 157 free (ptr - sizeof (__cxa_exception));
52a11cbf 158}