]> gcc.gnu.org Git - gcc.git/blame - boehm-gc/gc_cpp.h
Merged GC 5.0alpha4 with local changes, plus:
[gcc.git] / boehm-gc / gc_cpp.h
CommitLineData
73ffefd0
TT
1#ifndef GC_CPP_H
2#define GC_CPP_H
3/****************************************************************************
4Copyright (c) 1994 by Xerox Corporation. All rights reserved.
5
6THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
7OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
8
9Permission is hereby granted to use or copy this program for any
10purpose, provided the above notices are retained on all copies.
11Permission to modify the code and to distribute modified code is
12granted, provided the above notices are retained, and a notice that
13the code was modified is included with the above copyright notice.
14****************************************************************************
15
16C++ Interface to the Boehm Collector
17
18 John R. Ellis and Jesse Hull
19 Last modified on Mon Jul 24 15:43:42 PDT 1995 by ellis
20
21This interface provides access to the Boehm collector. It provides
22basic facilities similar to those described in "Safe, Efficient
23Garbage Collection for C++", by John R. Elis and David L. Detlefs
24(ftp.parc.xerox.com:/pub/ellis/gc).
25
26All heap-allocated objects are either "collectable" or
27"uncollectable". Programs must explicitly delete uncollectable
28objects, whereas the garbage collector will automatically delete
29collectable objects when it discovers them to be inaccessible.
30Collectable objects may freely point at uncollectable objects and vice
31versa.
32
33Objects allocated with the built-in "::operator new" are uncollectable.
34
35Objects derived from class "gc" are collectable. For example:
36
37 class A: public gc {...};
38 A* a = new A; // a is collectable.
39
40Collectable instances of non-class types can be allocated using the GC
41placement:
42
43 typedef int A[ 10 ];
44 A* a = new (GC) A;
45
46Uncollectable instances of classes derived from "gc" can be allocated
47using the NoGC placement:
48
49 class A: public gc {...};
50 A* a = new (NoGC) A; // a is uncollectable.
51
52Both uncollectable and collectable objects can be explicitly deleted
53with "delete", which invokes an object's destructors and frees its
54storage immediately.
55
56A collectable object may have a clean-up function, which will be
57invoked when the collector discovers the object to be inaccessible.
58An object derived from "gc_cleanup" or containing a member derived
59from "gc_cleanup" has a default clean-up function that invokes the
60object's destructors. Explicit clean-up functions may be specified as
61an additional placement argument:
62
63 A* a = ::new (GC, MyCleanup) A;
64
65An object is considered "accessible" by the collector if it can be
66reached by a path of pointers from static variables, automatic
67variables of active functions, or from some object with clean-up
68enabled; pointers from an object to itself are ignored.
69
70Thus, if objects A and B both have clean-up functions, and A points at
71B, B is considered accessible. After A's clean-up is invoked and its
72storage released, B will then become inaccessible and will have its
73clean-up invoked. If A points at B and B points to A, forming a
74cycle, then that's considered a storage leak, and neither will be
75collectable. See the interface gc.h for low-level facilities for
76handling such cycles of objects with clean-up.
77
78The collector cannot guarrantee that it will find all inaccessible
79objects. In practice, it finds almost all of them.
80
81
82Cautions:
83
841. Be sure the collector has been augmented with "make c++".
85
862. If your compiler supports the new "operator new[]" syntax, then
87add -DOPERATOR_NEW_ARRAY to the Makefile.
88
89If your compiler doesn't support "operator new[]", beware that an
90array of type T, where T is derived from "gc", may or may not be
91allocated as a collectable object (it depends on the compiler). Use
92the explicit GC placement to make the array collectable. For example:
93
94 class A: public gc {...};
95 A* a1 = new A[ 10 ]; // collectable or uncollectable?
96 A* a2 = new (GC) A[ 10 ]; // collectable
97
983. The destructors of collectable arrays of objects derived from
99"gc_cleanup" will not be invoked properly. For example:
100
101 class A: public gc_cleanup {...};
102 A* a = new (GC) A[ 10 ]; // destructors not invoked correctly
103
104Typically, only the destructor for the first element of the array will
105be invoked when the array is garbage-collected. To get all the
106destructors of any array executed, you must supply an explicit
107clean-up function:
108
109 A* a = new (GC, MyCleanUp) A[ 10 ];
110
111(Implementing clean-up of arrays correctly, portably, and in a way
112that preserves the correct exception semantics requires a language
113extension, e.g. the "gc" keyword.)
114
1154. Compiler bugs:
116
117* Solaris 2's CC (SC3.0) doesn't implement t->~T() correctly, so the
118destructors of classes derived from gc_cleanup won't be invoked.
119You'll have to explicitly register a clean-up function with
120new-placement syntax.
121
122* Evidently cfront 3.0 does not allow destructors to be explicitly
123invoked using the ANSI-conforming syntax t->~T(). If you're using
124cfront 3.0, you'll have to comment out the class gc_cleanup, which
125uses explicit invocation.
126
127****************************************************************************/
128
129#include "gc.h"
130
131#ifndef THINK_CPLUS
132#define _cdecl
133#endif
134
135#if ! defined( OPERATOR_NEW_ARRAY ) \
20bbd3cd
TT
136 && (__BORLANDC__ >= 0x450 || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6) \
137 || __WATCOMC__ >= 1050)
73ffefd0
TT
138# define OPERATOR_NEW_ARRAY
139#endif
140
141enum GCPlacement {GC, NoGC, PointerFreeGC};
142
143class gc {public:
144 inline void* operator new( size_t size );
145 inline void* operator new( size_t size, GCPlacement gcp );
146 inline void operator delete( void* obj );
147
148#ifdef OPERATOR_NEW_ARRAY
149 inline void* operator new[]( size_t size );
150 inline void* operator new[]( size_t size, GCPlacement gcp );
151 inline void operator delete[]( void* obj );
152#endif /* OPERATOR_NEW_ARRAY */
153 };
154 /*
155 Instances of classes derived from "gc" will be allocated in the
156 collected heap by default, unless an explicit NoGC placement is
157 specified. */
158
159class gc_cleanup: virtual public gc {public:
160 inline gc_cleanup();
161 inline virtual ~gc_cleanup();
162private:
163 inline static void _cdecl cleanup( void* obj, void* clientData );};
164 /*
165 Instances of classes derived from "gc_cleanup" will be allocated
166 in the collected heap by default. When the collector discovers an
167 inaccessible object derived from "gc_cleanup" or containing a
168 member derived from "gc_cleanup", its destructors will be
169 invoked. */
170
171extern "C" {typedef void (*GCCleanUpFunc)( void* obj, void* clientData );}
172
173inline void* operator new(
174 size_t size,
175 GCPlacement gcp,
176 GCCleanUpFunc cleanup = 0,
177 void* clientData = 0 );
178 /*
179 Allocates a collectable or uncollected object, according to the
180 value of "gcp".
181
182 For collectable objects, if "cleanup" is non-null, then when the
183 allocated object "obj" becomes inaccessible, the collector will
184 invoke the function "cleanup( obj, clientData )" but will not
185 invoke the object's destructors. It is an error to explicitly
186 delete an object allocated with a non-null "cleanup".
187
188 It is an error to specify a non-null "cleanup" with NoGC or for
189 classes derived from "gc_cleanup" or containing members derived
190 from "gc_cleanup". */
191
192#ifdef OPERATOR_NEW_ARRAY
193
194inline void* operator new[](
195 size_t size,
196 GCPlacement gcp,
197 GCCleanUpFunc cleanup = 0,
198 void* clientData = 0 );
199 /*
200 The operator new for arrays, identical to the above. */
201
202#endif /* OPERATOR_NEW_ARRAY */
203
204/****************************************************************************
205
206Inline implementation
207
208****************************************************************************/
209
210inline void* gc::operator new( size_t size ) {
211 return GC_MALLOC( size );}
212
213inline void* gc::operator new( size_t size, GCPlacement gcp ) {
214 if (gcp == GC)
215 return GC_MALLOC( size );
20bbd3cd
TT
216 else if (gcp == PointerFreeGC)
217 return GC_MALLOC_ATOMIC( size );
73ffefd0
TT
218 else
219 return GC_MALLOC_UNCOLLECTABLE( size );}
220
221inline void gc::operator delete( void* obj ) {
222 GC_FREE( obj );}
223
224
225#ifdef OPERATOR_NEW_ARRAY
226
227inline void* gc::operator new[]( size_t size ) {
228 return gc::operator new( size );}
229
230inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
231 return gc::operator new( size, gcp );}
232
233inline void gc::operator delete[]( void* obj ) {
234 gc::operator delete( obj );}
235
236#endif /* OPERATOR_NEW_ARRAY */
237
238
239inline gc_cleanup::~gc_cleanup() {
20bbd3cd 240 GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );}
73ffefd0
TT
241
242inline void gc_cleanup::cleanup( void* obj, void* displ ) {
243 ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
244
245inline gc_cleanup::gc_cleanup() {
246 GC_finalization_proc oldProc;
247 void* oldData;
248 void* base = GC_base( (void *) this );
249 if (0 == base) return;
250 GC_REGISTER_FINALIZER_IGNORE_SELF(
251 base, cleanup, (void*) ((char*) this - (char*) base),
252 &oldProc, &oldData );
253 if (0 != oldProc) {
254 GC_REGISTER_FINALIZER_IGNORE_SELF( base, oldProc, oldData, 0, 0 );}}
255
256inline void* operator new(
257 size_t size,
258 GCPlacement gcp,
259 GCCleanUpFunc cleanup,
260 void* clientData )
261{
262 void* obj;
263
264 if (gcp == GC) {
265 obj = GC_MALLOC( size );
266 if (cleanup != 0)
267 GC_REGISTER_FINALIZER_IGNORE_SELF(
268 obj, cleanup, clientData, 0, 0 );}
269 else if (gcp == PointerFreeGC) {
270 obj = GC_MALLOC_ATOMIC( size );}
271 else {
272 obj = GC_MALLOC_UNCOLLECTABLE( size );};
273 return obj;}
274
275
276#ifdef OPERATOR_NEW_ARRAY
277
278inline void* operator new[](
279 size_t size,
280 GCPlacement gcp,
281 GCCleanUpFunc cleanup,
282 void* clientData )
283{
284 return ::operator new( size, gcp, cleanup, clientData );}
285
286#endif /* OPERATOR_NEW_ARRAY */
287
288
289#endif /* GC_CPP_H */
290
This page took 0.092103 seconds and 5 git commands to generate.