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