OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [libsupc++/] [eh_alloc.cc] - Blame information for rev 747

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 742 jeremybenn
// -*- C++ -*- Allocate exception objects.
2
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2011
3
// Free Software Foundation, Inc.
4
//
5
// This file is part of GCC.
6
//
7
// GCC is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License as published by
9
// the Free Software Foundation; either version 3, or (at your option)
10
// any later version.
11
//
12
// GCC is distributed in the hope that it will be useful,
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
// Under Section 7 of GPL version 3, you are granted additional
18
// permissions described in the GCC Runtime Library Exception, version
19
// 3.1, as published by the Free Software Foundation.
20
 
21
// You should have received a copy of the GNU General Public License and
22
// a copy of the GCC Runtime Library Exception along with this program;
23
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
24
// <http://www.gnu.org/licenses/>.
25
 
26
// This is derived from the C++ ABI for IA-64.  Where we diverge
27
// for cross-architecture compatibility are noted with "@@@".
28
 
29
#include <bits/c++config.h>
30
#include <cstdlib>
31
#if _GLIBCXX_HOSTED
32
#include <cstring>
33
#endif
34
#include <climits>
35
#include <exception>
36
#include "unwind-cxx.h"
37
#include <ext/concurrence.h>
38
 
39
#if _GLIBCXX_HOSTED
40
using std::free;
41
using std::malloc;
42
using std::memset;
43
#else
44
// In a freestanding environment, these functions may not be available
45
// -- but for now, we assume that they are.
46
extern "C" void *malloc (std::size_t);
47
extern "C" void free(void *);
48
extern "C" void *memset (void *, int, std::size_t);
49
#endif
50
 
51
using namespace __cxxabiv1;
52
 
53
// ??? How to control these parameters.
54
 
55
// Guess from the size of basic types how large a buffer is reasonable.
56
// Note that the basic c++ exception header has 13 pointers and 2 ints,
57
// so on a system with PSImode pointers we're talking about 56 bytes
58
// just for overhead.
59
 
60
#if INT_MAX == 32767
61
# define EMERGENCY_OBJ_SIZE     128
62
# define EMERGENCY_OBJ_COUNT    16
63
#elif LONG_MAX == 2147483647
64
# define EMERGENCY_OBJ_SIZE     512
65
# define EMERGENCY_OBJ_COUNT    32
66
#else
67
# define EMERGENCY_OBJ_SIZE     1024
68
# define EMERGENCY_OBJ_COUNT    64
69
#endif
70
 
71
#ifndef __GTHREADS
72
# undef EMERGENCY_OBJ_COUNT
73
# define EMERGENCY_OBJ_COUNT    4
74
#endif
75
 
76
#if INT_MAX == 32767 || EMERGENCY_OBJ_COUNT <= 32
77
typedef unsigned int bitmask_type;
78
#else
79
typedef unsigned long bitmask_type;
80
#endif
81
 
82
 
83
typedef char one_buffer[EMERGENCY_OBJ_SIZE] __attribute__((aligned));
84
static one_buffer emergency_buffer[EMERGENCY_OBJ_COUNT];
85
static bitmask_type emergency_used;
86
 
87
static __cxa_dependent_exception dependents_buffer[EMERGENCY_OBJ_COUNT];
88
static bitmask_type dependents_used;
89
 
90
namespace
91
{
92
  // A single mutex controlling emergency allocations.
93
  __gnu_cxx::__mutex emergency_mutex;
94
}
95
 
96
extern "C" void *
97
__cxxabiv1::__cxa_allocate_exception(std::size_t thrown_size) _GLIBCXX_NOTHROW
98
{
99
  void *ret;
100
 
101
  thrown_size += sizeof (__cxa_refcounted_exception);
102
  ret = malloc (thrown_size);
103
 
104
  if (! ret)
105
    {
106
      __gnu_cxx::__scoped_lock sentry(emergency_mutex);
107
 
108
      bitmask_type used = emergency_used;
109
      unsigned int which = 0;
110
 
111
      if (thrown_size > EMERGENCY_OBJ_SIZE)
112
        goto failed;
113
      while (used & 1)
114
        {
115
          used >>= 1;
116
          if (++which >= EMERGENCY_OBJ_COUNT)
117
            goto failed;
118
        }
119
 
120
      emergency_used |= (bitmask_type)1 << which;
121
      ret = &emergency_buffer[which][0];
122
 
123
    failed:;
124
 
125
      if (!ret)
126
        std::terminate ();
127
    }
128
 
129
  // We have an uncaught exception as soon as we allocate memory.  This
130
  // yields uncaught_exception() true during the copy-constructor that
131
  // initializes the exception object.  See Issue 475.
132
  __cxa_eh_globals *globals = __cxa_get_globals ();
133
  globals->uncaughtExceptions += 1;
134
 
135
  memset (ret, 0, sizeof (__cxa_refcounted_exception));
136
 
137
  return (void *)((char *)ret + sizeof (__cxa_refcounted_exception));
138
}
139
 
140
 
141
extern "C" void
142
__cxxabiv1::__cxa_free_exception(void *vptr) _GLIBCXX_NOTHROW
143
{
144
  char *base = (char *) emergency_buffer;
145
  char *ptr = (char *) vptr;
146
  if (ptr >= base
147
      && ptr < base + sizeof (emergency_buffer))
148
    {
149
      const unsigned int which
150
        = (unsigned) (ptr - base) / EMERGENCY_OBJ_SIZE;
151
 
152
      __gnu_cxx::__scoped_lock sentry(emergency_mutex);
153
      emergency_used &= ~((bitmask_type)1 << which);
154
    }
155
  else
156
    free (ptr - sizeof (__cxa_refcounted_exception));
157
}
158
 
159
 
160
extern "C" __cxa_dependent_exception*
161
__cxxabiv1::__cxa_allocate_dependent_exception() _GLIBCXX_NOTHROW
162
{
163
  __cxa_dependent_exception *ret;
164
 
165
  ret = static_cast<__cxa_dependent_exception*>
166
    (malloc (sizeof (__cxa_dependent_exception)));
167
 
168
  if (!ret)
169
    {
170
      __gnu_cxx::__scoped_lock sentry(emergency_mutex);
171
 
172
      bitmask_type used = dependents_used;
173
      unsigned int which = 0;
174
 
175
      while (used & 1)
176
        {
177
          used >>= 1;
178
          if (++which >= EMERGENCY_OBJ_COUNT)
179
            goto failed;
180
        }
181
 
182
      dependents_used |= (bitmask_type)1 << which;
183
      ret = &dependents_buffer[which];
184
 
185
    failed:;
186
 
187
      if (!ret)
188
        std::terminate ();
189
    }
190
 
191
  // We have an uncaught exception as soon as we allocate memory.  This
192
  // yields uncaught_exception() true during the copy-constructor that
193
  // initializes the exception object.  See Issue 475.
194
  __cxa_eh_globals *globals = __cxa_get_globals ();
195
  globals->uncaughtExceptions += 1;
196
 
197
  memset (ret, 0, sizeof (__cxa_dependent_exception));
198
 
199
  return ret;
200
}
201
 
202
 
203
extern "C" void
204
__cxxabiv1::__cxa_free_dependent_exception
205
  (__cxa_dependent_exception *vptr) _GLIBCXX_NOTHROW
206
{
207
  char *base = (char *) dependents_buffer;
208
  char *ptr = (char *) vptr;
209
  if (ptr >= base
210
      && ptr < base + sizeof (dependents_buffer))
211
    {
212
      const unsigned int which
213
        = (unsigned) (ptr - base) / sizeof (__cxa_dependent_exception);
214
 
215
      __gnu_cxx::__scoped_lock sentry(emergency_mutex);
216
      dependents_used &= ~((bitmask_type)1 << which);
217
    }
218
  else
219
    free (vptr);
220
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.