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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [boehm-gc/] [include/] [gc_cpp.h] - Blame information for rev 721

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 721 jeremybenn
#ifndef GC_CPP_H
2
#define GC_CPP_H
3
/****************************************************************************
4
Copyright (c) 1994 by Xerox Corporation.  All rights reserved.
5
 
6
THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7
OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
8
 
9
Permission is hereby granted to use or copy this program for any
10
purpose, provided the above notices are retained on all copies.
11
Permission to modify the code and to distribute modified code is
12
granted, provided the above notices are retained, and a notice that
13
the code was modified is included with the above copyright notice.
14
****************************************************************************
15
 
16
C++ Interface to the Boehm Collector
17
 
18
    John R. Ellis and Jesse Hull
19
 
20
This interface provides access to the Boehm collector.  It provides
21
basic facilities similar to those described in "Safe, Efficient
22
Garbage Collection for C++", by John R. Elis and David L. Detlefs
23
(ftp://ftp.parc.xerox.com/pub/ellis/gc).
24
 
25
All heap-allocated objects are either "collectable" or
26
"uncollectable".  Programs must explicitly delete uncollectable
27
objects, whereas the garbage collector will automatically delete
28
collectable objects when it discovers them to be inaccessible.
29
Collectable objects may freely point at uncollectable objects and vice
30
versa.
31
 
32
Objects allocated with the built-in "::operator new" are uncollectable.
33
 
34
Objects derived from class "gc" are collectable.  For example:
35
 
36
    class A: public gc {...};
37
    A* a = new A;       // a is collectable.
38
 
39
Collectable instances of non-class types can be allocated using the GC
40
(or UseGC) placement:
41
 
42
    typedef int A[ 10 ];
43
    A* a = new (GC) A;
44
 
45
Uncollectable instances of classes derived from "gc" can be allocated
46
using the NoGC placement:
47
 
48
    class A: public gc {...};
49
    A* a = new (NoGC) A;   // a is uncollectable.
50
 
51
Both uncollectable and collectable objects can be explicitly deleted
52
with "delete", which invokes an object's destructors and frees its
53
storage immediately.
54
 
55
A collectable object may have a clean-up function, which will be
56
invoked when the collector discovers the object to be inaccessible.
57
An object derived from "gc_cleanup" or containing a member derived
58
from "gc_cleanup" has a default clean-up function that invokes the
59
object's destructors.  Explicit clean-up functions may be specified as
60
an additional placement argument:
61
 
62
    A* a = ::new (GC, MyCleanup) A;
63
 
64
An object is considered "accessible" by the collector if it can be
65
reached by a path of pointers from static variables, automatic
66
variables of active functions, or from some object with clean-up
67
enabled; pointers from an object to itself are ignored.
68
 
69
Thus, if objects A and B both have clean-up functions, and A points at
70
B, B is considered accessible.  After A's clean-up is invoked and its
71
storage released, B will then become inaccessible and will have its
72
clean-up invoked.  If A points at B and B points to A, forming a
73
cycle, then that's considered a storage leak, and neither will be
74
collectable.  See the interface gc.h for low-level facilities for
75
handling such cycles of objects with clean-up.
76
 
77
The collector cannot guarantee that it will find all inaccessible
78
objects.  In practice, it finds almost all of them.
79
 
80
 
81
Cautions:
82
 
83
1. Be sure the collector has been augmented with "make c++".
84
 
85
2.  If your compiler supports the new "operator new[]" syntax, then
86
add -DGC_OPERATOR_NEW_ARRAY to the Makefile.
87
 
88
If your compiler doesn't support "operator new[]", beware that an
89
array of type T, where T is derived from "gc", may or may not be
90
allocated as a collectable object (it depends on the compiler).  Use
91
the explicit GC placement to make the array collectable.  For example:
92
 
93
    class A: public gc {...};
94
    A* a1 = new A[ 10 ];        // collectable or uncollectable?
95
    A* a2 = new (GC) A[ 10 ];   // collectable
96
 
97
3. The destructors of collectable arrays of objects derived from
98
"gc_cleanup" will not be invoked properly.  For example:
99
 
100
    class A: public gc_cleanup {...};
101
    A* a = new (GC) A[ 10 ];    // destructors not invoked correctly
102
 
103
Typically, only the destructor for the first element of the array will
104
be invoked when the array is garbage-collected.  To get all the
105
destructors of any array executed, you must supply an explicit
106
clean-up function:
107
 
108
    A* a = new (GC, MyCleanUp) A[ 10 ];
109
 
110
(Implementing clean-up of arrays correctly, portably, and in a way
111
that preserves the correct exception semantics requires a language
112
extension, e.g. the "gc" keyword.)
113
 
114
4. Compiler bugs:
115
 
116
* Solaris 2's CC (SC3.0) doesn't implement t->~T() correctly, so the
117
destructors of classes derived from gc_cleanup won't be invoked.
118
You'll have to explicitly register a clean-up function with
119
new-placement syntax.
120
 
121
* Evidently cfront 3.0 does not allow destructors to be explicitly
122
invoked using the ANSI-conforming syntax t->~T().  If you're using
123
cfront 3.0, you'll have to comment out the class gc_cleanup, which
124
uses explicit invocation.
125
 
126
5. GC name conflicts:
127
 
128
Many other systems seem to use the identifier "GC" as an abbreviation
129
for "Graphics Context".  Since version 5.0, GC placement has been replaced
130
by UseGC.  GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined.
131
 
132
****************************************************************************/
133
 
134
#include "gc.h"
135
 
136
#ifndef THINK_CPLUS
137
#  define GC_cdecl
138
#else
139
#  define GC_cdecl _cdecl
140
#endif
141
 
142
#if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \
143
    && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \
144
    && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \
145
        || (defined(__GNUC__) && \
146
            (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \
147
        || (defined(__WATCOMC__) && __WATCOMC__ < 1050))
148
#   define GC_NO_OPERATOR_NEW_ARRAY
149
#endif
150
 
151
#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY)
152
#   define GC_OPERATOR_NEW_ARRAY
153
#endif
154
 
155
#if    ! defined ( __BORLANDC__ )  /* Confuses the Borland compiler. */ \
156
    && ! defined ( __sgi )
157
#  define GC_PLACEMENT_DELETE
158
#endif
159
 
160
enum GCPlacement {UseGC,
161
#ifndef GC_NAME_CONFLICT
162
                  GC=UseGC,
163
#endif
164
                  NoGC, PointerFreeGC};
165
 
166
class gc {public:
167
    inline void* operator new( size_t size );
168
    inline void* operator new( size_t size, GCPlacement gcp );
169
    inline void* operator new( size_t size, void *p );
170
        /* Must be redefined here, since the other overloadings */
171
        /* hide the global definition.                          */
172
    inline void operator delete( void* obj );
173
#   ifdef GC_PLACEMENT_DELETE  
174
      inline void operator delete( void*, void* );
175
#   endif
176
 
177
#ifdef GC_OPERATOR_NEW_ARRAY
178
    inline void* operator new[]( size_t size );
179
    inline void* operator new[]( size_t size, GCPlacement gcp );
180
    inline void* operator new[]( size_t size, void *p );
181
    inline void operator delete[]( void* obj );
182
#   ifdef GC_PLACEMENT_DELETE
183
      inline void gc::operator delete[]( void*, void* );
184
#   endif
185
#endif /* GC_OPERATOR_NEW_ARRAY */
186
    };
187
    /*
188
    Instances of classes derived from "gc" will be allocated in the
189
    collected heap by default, unless an explicit NoGC placement is
190
    specified. */
191
 
192
class gc_cleanup: virtual public gc {public:
193
    inline gc_cleanup();
194
    inline virtual ~gc_cleanup();
195
private:
196
    inline static void GC_cdecl cleanup( void* obj, void* clientData );};
197
    /*
198
    Instances of classes derived from "gc_cleanup" will be allocated
199
    in the collected heap by default.  When the collector discovers an
200
    inaccessible object derived from "gc_cleanup" or containing a
201
    member derived from "gc_cleanup", its destructors will be
202
    invoked. */
203
 
204
extern "C" {typedef void (*GCCleanUpFunc)( void* obj, void* clientData );}
205
 
206
#ifdef _MSC_VER
207
  // Disable warning that "no matching operator delete found; memory will
208
  // not be freed if initialization throws an exception"
209
# pragma warning(disable:4291)
210
#endif
211
 
212
inline void* operator new(
213
    size_t size,
214
    GCPlacement gcp,
215
    GCCleanUpFunc cleanup = 0,
216
    void* clientData = 0 );
217
    /*
218
    Allocates a collectable or uncollected object, according to the
219
    value of "gcp".
220
 
221
    For collectable objects, if "cleanup" is non-null, then when the
222
    allocated object "obj" becomes inaccessible, the collector will
223
    invoke the function "cleanup( obj, clientData )" but will not
224
    invoke the object's destructors.  It is an error to explicitly
225
    delete an object allocated with a non-null "cleanup".
226
 
227
    It is an error to specify a non-null "cleanup" with NoGC or for
228
    classes derived from "gc_cleanup" or containing members derived
229
    from "gc_cleanup". */
230
 
231
 
232
#ifdef _MSC_VER
233
 /** This ensures that the system default operator new[] doesn't get
234
  *  undefined, which is what seems to happen on VC++ 6 for some reason
235
  *  if we define a multi-argument operator new[].
236
  *  There seems to be really redirect new in this environment without
237
  *  including this everywhere.
238
  */
239
 void *operator new[]( size_t size );
240
 
241
 void operator delete[](void* obj);
242
 
243
 void* operator new( size_t size);
244
 
245
 void operator delete(void* obj);
246
 
247
 // This new operator is used by VC++ in case of Debug builds !
248
 void* operator new(  size_t size,
249
                      int ,//nBlockUse,
250
                      const char * szFileName,
251
                      int nLine );
252
#endif /* _MSC_VER */
253
 
254
 
255
#ifdef GC_OPERATOR_NEW_ARRAY
256
 
257
inline void* operator new[](
258
    size_t size,
259
    GCPlacement gcp,
260
    GCCleanUpFunc cleanup = 0,
261
    void* clientData = 0 );
262
    /*
263
    The operator new for arrays, identical to the above. */
264
 
265
#endif /* GC_OPERATOR_NEW_ARRAY */
266
 
267
/****************************************************************************
268
 
269
Inline implementation
270
 
271
****************************************************************************/
272
 
273
inline void* gc::operator new( size_t size ) {
274
    return GC_MALLOC( size );}
275
 
276
inline void* gc::operator new( size_t size, GCPlacement gcp ) {
277
    if (gcp == UseGC)
278
        return GC_MALLOC( size );
279
    else if (gcp == PointerFreeGC)
280
        return GC_MALLOC_ATOMIC( size );
281
    else
282
        return GC_MALLOC_UNCOLLECTABLE( size );}
283
 
284
inline void* gc::operator new( size_t size, void *p ) {
285
    return p;}
286
 
287
inline void gc::operator delete( void* obj ) {
288
    GC_FREE( obj );}
289
 
290
#ifdef GC_PLACEMENT_DELETE
291
  inline void gc::operator delete( void*, void* ) {}
292
#endif
293
 
294
#ifdef GC_OPERATOR_NEW_ARRAY
295
 
296
inline void* gc::operator new[]( size_t size ) {
297
    return gc::operator new( size );}
298
 
299
inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
300
    return gc::operator new( size, gcp );}
301
 
302
inline void* gc::operator new[]( size_t size, void *p ) {
303
    return p;}
304
 
305
inline void gc::operator delete[]( void* obj ) {
306
    gc::operator delete( obj );}
307
 
308
#ifdef GC_PLACEMENT_DELETE
309
  inline void gc::operator delete[]( void*, void* ) {}
310
#endif
311
 
312
#endif /* GC_OPERATOR_NEW_ARRAY */
313
 
314
 
315
inline gc_cleanup::~gc_cleanup() {
316
    GC_register_finalizer_ignore_self( GC_base(this), 0, 0, 0, 0 );}
317
 
318
inline void gc_cleanup::cleanup( void* obj, void* displ ) {
319
    ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
320
 
321
inline gc_cleanup::gc_cleanup() {
322
    GC_finalization_proc oldProc;
323
    void* oldData;
324
    void* base = GC_base( (void *) this );
325
    if (0 != base)  {
326
      // Don't call the debug version, since this is a real base address.
327
      GC_register_finalizer_ignore_self(
328
        base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base),
329
        &oldProc, &oldData );
330
      if (0 != oldProc) {
331
        GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );}}}
332
 
333
inline void* operator new(
334
    size_t size,
335
    GCPlacement gcp,
336
    GCCleanUpFunc cleanup,
337
    void* clientData )
338
{
339
    void* obj;
340
 
341
    if (gcp == UseGC) {
342
        obj = GC_MALLOC( size );
343
        if (cleanup != 0)
344
            GC_REGISTER_FINALIZER_IGNORE_SELF(
345
                obj, cleanup, clientData, 0, 0 );}
346
    else if (gcp == PointerFreeGC) {
347
        obj = GC_MALLOC_ATOMIC( size );}
348
    else {
349
        obj = GC_MALLOC_UNCOLLECTABLE( size );};
350
    return obj;}
351
 
352
 
353
#ifdef GC_OPERATOR_NEW_ARRAY
354
 
355
inline void* operator new[](
356
    size_t size,
357
    GCPlacement gcp,
358
    GCCleanUpFunc cleanup,
359
    void* clientData )
360
{
361
    return ::operator new( size, gcp, cleanup, clientData );}
362
 
363
#endif /* GC_OPERATOR_NEW_ARRAY */
364
 
365
 
366
#endif /* GC_CPP_H */
367
 

powered by: WebSVN 2.1.0

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