]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/libsupc++/eh_alloc.cc
builtins.c (expand_builtin_memcpy): Use mode of dest_addr for intermediate computation.
[thirdparty/gcc.git] / libstdc++-v3 / libsupc++ / eh_alloc.cc
CommitLineData
52a11cbf
RH
1// -*- C++ -*- Allocate exception objects.
2// Copyright (C) 2001 Free Software Foundation, Inc.
3//
4// This file is part of GNU CC.
5//
6// GNU CC 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 2, or (at your option)
9// any later version.
10//
11// GNU CC 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// You should have received a copy of the GNU General Public License
17// along with GNU CC; see the file COPYING. If not, write to
18// the Free Software Foundation, 59 Temple Place - Suite 330,
19// Boston, MA 02111-1307, USA.
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
52a11cbf
RH
33#include <cstdlib>
34#include <cstring>
213c2316 35#include <climits>
93b85586 36#include <exception>
52a11cbf 37#include "unwind-cxx.h"
7628e178
LR
38#include "bits/c++config.h"
39#include "bits/gthr.h"
52a11cbf
RH
40
41using namespace __cxxabiv1;
42
43
44// ??? How to control these parameters.
45
46// Guess from the size of basic types how large a buffer is reasonable.
47// Note that the basic c++ exception header has 13 pointers and 2 ints,
48// so on a system with PSImode pointers we're talking about 56 bytes
49// just for overhead.
50
51#if INT_MAX == 32767
52# define EMERGENCY_OBJ_SIZE 128
53# define EMERGENCY_OBJ_COUNT 16
54#elif LONG_MAX == 2147483647
55# define EMERGENCY_OBJ_SIZE 512
56# define EMERGENCY_OBJ_COUNT 32
57#else
58# define EMERGENCY_OBJ_SIZE 1024
59# define EMERGENCY_OBJ_COUNT 64
60#endif
61
62#ifndef __GTHREADS
63# undef EMERGENCY_OBJ_COUNT
64# define EMERGENCY_OBJ_COUNT 4
65#endif
66
67#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
68typedef unsigned int bitmask_type;
69#else
70typedef unsigned long bitmask_type;
71#endif
72
73
74typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
75static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
76static bitmask_type emergency_used;
77
78
79#ifdef __GTHREADS
80#ifdef __GTHREAD_MUTEX_INIT
81static __gthread_mutex_t emergency_mutex =__GTHREAD_MUTEX_INIT;
82#else
83static __gthread_mutex_t emergency_mutex;
84#endif
85
86#ifdef __GTHREAD_MUTEX_INIT_FUNCTION
87static void
88emergency_mutex_init ()
89{
90 __GTHREAD_MUTEX_INIT_FUNCTION (&emergency_mutex);
91}
92#endif
93#endif
94
95
96extern "C" void *
97__cxa_allocate_exception(std::size_t thrown_size)
98{
99 void *ret;
100
101 thrown_size += sizeof (__cxa_exception);
1044b043 102 ret = std::malloc (thrown_size);
52a11cbf
RH
103
104 if (! ret)
105 {
106#ifdef __GTHREADS
107#ifdef __GTHREAD_MUTEX_INIT_FUNCTION
108 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
109 __gthread_once (&once, emergency_mutex_init);
110#endif
111 __gthread_mutex_lock (&emergency_mutex);
112#endif
113
114 bitmask_type used = emergency_used;
115 unsigned int which = 0;
116
f847167e
NS
117 if (thrown_size > EMERGENCY_OBJ_SIZE)
118 goto failed;
52a11cbf
RH
119 while (used & 1)
120 {
121 used >>= 1;
122 if (++which >= EMERGENCY_OBJ_COUNT)
f847167e 123 goto failed;
52a11cbf
RH
124 }
125
126 emergency_used |= (bitmask_type)1 << which;
127 ret = &emergency_buffer[which][0];
128
f847167e 129 failed:;
52a11cbf
RH
130#ifdef __GTHREADS
131 __gthread_mutex_unlock (&emergency_mutex);
132#endif
f847167e
NS
133 if (!ret)
134 std::terminate ();
52a11cbf
RH
135 }
136
eeff8d2c 137 std::memset (ret, 0, sizeof (__cxa_exception));
52a11cbf
RH
138
139 return (void *)((char *)ret + sizeof (__cxa_exception));
140}
141
142
143extern "C" void
144__cxa_free_exception(void *vptr)
145{
146 char *ptr = (char *) vptr;
147 if (ptr >= &emergency_buffer[0][0]
148 && ptr < &emergency_buffer[0][0] + sizeof (emergency_buffer))
149 {
150 unsigned int which
151 = (unsigned)(ptr - &emergency_buffer[0][0]) / EMERGENCY_OBJ_SIZE;
152
153#ifdef __GTHREADS
154 __gthread_mutex_lock (&emergency_mutex);
155 emergency_used &= ~((bitmask_type)1 << which);
156 __gthread_mutex_unlock (&emergency_mutex);
157#else
158 emergency_used &= ~((bitmask_type)1 << which);
159#endif
160 }
161 else
1044b043 162 std::free (ptr - sizeof (__cxa_exception));
52a11cbf 163}