Import boehm-gc snapshot, taken from
[official-gcc.git] / boehm-gc / include / gc_cpp.h
blob6882786b0a5434713f2f60b3e2d031760aaef43d
1 /*
2 * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
7 * Permission is hereby granted to use or copy this program for any
8 * purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is
10 * granted, provided the above notices are retained, and a notice that
11 * the code was modified is included with the above copyright notice.
14 #ifndef GC_CPP_H
15 #define GC_CPP_H
17 /****************************************************************************
18 C++ Interface to the Boehm Collector
20 John R. Ellis and Jesse Hull
22 This interface provides access to the Boehm collector. It provides
23 basic facilities similar to those described in "Safe, Efficient
24 Garbage Collection for C++", by John R. Elis and David L. Detlefs
25 (ftp://ftp.parc.xerox.com/pub/ellis/gc).
27 All heap-allocated objects are either "collectable" or
28 "uncollectable". Programs must explicitly delete uncollectable
29 objects, whereas the garbage collector will automatically delete
30 collectable objects when it discovers them to be inaccessible.
31 Collectable objects may freely point at uncollectable objects and vice
32 versa.
34 Objects allocated with the built-in "::operator new" are uncollectable.
36 Objects derived from class "gc" are collectable. For example:
38 class A: public gc {...};
39 A* a = new A; // a is collectable.
41 Collectable instances of non-class types can be allocated using the GC
42 (or UseGC) placement:
44 typedef int A[ 10 ];
45 A* a = new (GC) A;
47 Uncollectable instances of classes derived from "gc" can be allocated
48 using the NoGC placement:
50 class A: public gc {...};
51 A* a = new (NoGC) A; // a is uncollectable.
53 The new(PointerFreeGC) syntax allows the allocation of collectable
54 objects that are not scanned by the collector. This useful if you
55 are allocating compressed data, bitmaps, or network packets. (In
56 the latter case, it may remove danger of unfriendly network packets
57 intentionally containing values that cause spurious memory retention.)
59 Both uncollectable and collectable objects can be explicitly deleted
60 with "delete", which invokes an object's destructors and frees its
61 storage immediately.
63 A collectable object may have a clean-up function, which will be
64 invoked when the collector discovers the object to be inaccessible.
65 An object derived from "gc_cleanup" or containing a member derived
66 from "gc_cleanup" has a default clean-up function that invokes the
67 object's destructors. Explicit clean-up functions may be specified as
68 an additional placement argument:
70 A* a = ::new (GC, MyCleanup) A;
72 An object is considered "accessible" by the collector if it can be
73 reached by a path of pointers from static variables, automatic
74 variables of active functions, or from some object with clean-up
75 enabled; pointers from an object to itself are ignored.
77 Thus, if objects A and B both have clean-up functions, and A points at
78 B, B is considered accessible. After A's clean-up is invoked and its
79 storage released, B will then become inaccessible and will have its
80 clean-up invoked. If A points at B and B points to A, forming a
81 cycle, then that's considered a storage leak, and neither will be
82 collectable. See the interface gc.h for low-level facilities for
83 handling such cycles of objects with clean-up.
85 The collector cannot guarantee that it will find all inaccessible
86 objects. In practice, it finds almost all of them.
89 Cautions:
91 1. Be sure the collector has been augmented with "make c++" or
92 "--enable-cplusplus".
94 2. If your compiler supports the new "operator new[]" syntax, then
95 add -DGC_OPERATOR_NEW_ARRAY to the Makefile.
97 If your compiler doesn't support "operator new[]", beware that an
98 array of type T, where T is derived from "gc", may or may not be
99 allocated as a collectable object (it depends on the compiler). Use
100 the explicit GC placement to make the array collectable. For example:
102 class A: public gc {...};
103 A* a1 = new A[ 10 ]; // collectable or uncollectable?
104 A* a2 = new (GC) A[ 10 ]; // collectable
106 3. The destructors of collectable arrays of objects derived from
107 "gc_cleanup" will not be invoked properly. For example:
109 class A: public gc_cleanup {...};
110 A* a = new (GC) A[ 10 ]; // destructors not invoked correctly
112 Typically, only the destructor for the first element of the array will
113 be invoked when the array is garbage-collected. To get all the
114 destructors of any array executed, you must supply an explicit
115 clean-up function:
117 A* a = new (GC, MyCleanUp) A[ 10 ];
119 (Implementing clean-up of arrays correctly, portably, and in a way
120 that preserves the correct exception semantics requires a language
121 extension, e.g. the "gc" keyword.)
123 4. Compiler bugs (now hopefully history):
125 * Solaris 2's CC (SC3.0) doesn't implement t->~T() correctly, so the
126 destructors of classes derived from gc_cleanup won't be invoked.
127 You'll have to explicitly register a clean-up function with
128 new-placement syntax.
130 * Evidently cfront 3.0 does not allow destructors to be explicitly
131 invoked using the ANSI-conforming syntax t->~T(). If you're using
132 cfront 3.0, you'll have to comment out the class gc_cleanup, which
133 uses explicit invocation.
135 5. GC name conflicts:
137 Many other systems seem to use the identifier "GC" as an abbreviation
138 for "Graphics Context". Since version 5.0, GC placement has been replaced
139 by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined.
141 ****************************************************************************/
143 #include "gc.h"
145 #ifdef GC_NAMESPACE
146 # define GC_NS_QUALIFY(T) boehmgc::T
147 #else
148 # define GC_NS_QUALIFY(T) T
149 #endif
151 #ifndef THINK_CPLUS
152 # define GC_cdecl GC_CALLBACK
153 #else
154 # define GC_cdecl _cdecl
155 #endif
157 #if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \
158 && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \
159 && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \
160 || (defined(__GNUC__) && \
161 (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \
162 || (defined(_MSC_VER) && _MSC_VER <= 1020) \
163 || (defined(__WATCOMC__) && __WATCOMC__ < 1050))
164 # define GC_NO_OPERATOR_NEW_ARRAY
165 #endif
167 #if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY)
168 # define GC_OPERATOR_NEW_ARRAY
169 #endif
171 #if (!defined(__BORLANDC__) || __BORLANDC__ > 0x0620) \
172 && ! defined ( __sgi ) && ! defined( __WATCOMC__ ) \
173 && (!defined(_MSC_VER) || _MSC_VER > 1020)
174 # define GC_PLACEMENT_DELETE
175 #endif
177 #ifdef GC_NAMESPACE
178 namespace boehmgc
180 #endif
182 enum GCPlacement {
183 UseGC,
184 # ifndef GC_NAME_CONFLICT
185 GC=UseGC,
186 # endif
187 NoGC,
188 PointerFreeGC
191 class gc {
192 public:
193 inline void* operator new( size_t size );
194 inline void* operator new( size_t size, GCPlacement gcp );
195 inline void* operator new( size_t size, void *p );
196 /* Must be redefined here, since the other overloadings */
197 /* hide the global definition. */
198 inline void operator delete( void* obj );
199 # ifdef GC_PLACEMENT_DELETE
200 inline void operator delete( void*, GCPlacement );
201 /* called if construction fails. */
202 inline void operator delete( void*, void* );
203 # endif
205 #ifdef GC_OPERATOR_NEW_ARRAY
206 inline void* operator new[]( size_t size );
207 inline void* operator new[]( size_t size, GCPlacement gcp );
208 inline void* operator new[]( size_t size, void *p );
209 inline void operator delete[]( void* obj );
210 # ifdef GC_PLACEMENT_DELETE
211 inline void operator delete[]( void*, GCPlacement );
212 inline void operator delete[]( void*, void* );
213 # endif
214 #endif /* GC_OPERATOR_NEW_ARRAY */
217 Instances of classes derived from "gc" will be allocated in the
218 collected heap by default, unless an explicit NoGC placement is
219 specified. */
221 class gc_cleanup: virtual public gc {
222 public:
223 inline gc_cleanup();
224 inline virtual ~gc_cleanup();
225 private:
226 inline static void GC_cdecl cleanup( void* obj, void* clientData );
229 Instances of classes derived from "gc_cleanup" will be allocated
230 in the collected heap by default. When the collector discovers an
231 inaccessible object derived from "gc_cleanup" or containing a
232 member derived from "gc_cleanup", its destructors will be
233 invoked. */
235 extern "C" {
236 typedef void (GC_CALLBACK * GCCleanUpFunc)( void* obj, void* clientData );
239 #ifdef GC_NAMESPACE
241 #endif
243 #ifdef _MSC_VER
244 // Disable warning that "no matching operator delete found; memory will
245 // not be freed if initialization throws an exception"
246 # pragma warning(disable:4291)
247 #endif
249 inline void* operator new( size_t size, GC_NS_QUALIFY(GCPlacement) gcp,
250 GC_NS_QUALIFY(GCCleanUpFunc) cleanup = 0,
251 void* clientData = 0 );
253 Allocates a collectable or uncollected object, according to the
254 value of "gcp".
256 For collectable objects, if "cleanup" is non-null, then when the
257 allocated object "obj" becomes inaccessible, the collector will
258 invoke the function "cleanup( obj, clientData )" but will not
259 invoke the object's destructors. It is an error to explicitly
260 delete an object allocated with a non-null "cleanup".
262 It is an error to specify a non-null "cleanup" with NoGC or for
263 classes derived from "gc_cleanup" or containing members derived
264 from "gc_cleanup". */
266 #ifdef GC_PLACEMENT_DELETE
267 inline void operator delete( void*, GC_NS_QUALIFY(GCPlacement),
268 GC_NS_QUALIFY(GCCleanUpFunc), void * );
269 #endif
271 #ifdef _MSC_VER
272 /** This ensures that the system default operator new[] doesn't get
273 * undefined, which is what seems to happen on VC++ 6 for some reason
274 * if we define a multi-argument operator new[].
275 * There seems to be no way to redirect new in this environment without
276 * including this everywhere.
278 # if _MSC_VER > 1020
279 void *operator new[]( size_t size );
280 void operator delete[]( void* obj );
281 # endif
283 void* operator new( size_t size );
284 void operator delete( void* obj );
286 // This new operator is used by VC++ in case of Debug builds !
287 void* operator new( size_t size, int /* nBlockUse */,
288 const char * szFileName, int nLine );
289 #endif /* _MSC_VER */
291 #ifdef GC_OPERATOR_NEW_ARRAY
292 inline void* operator new[]( size_t size, GC_NS_QUALIFY(GCPlacement) gcp,
293 GC_NS_QUALIFY(GCCleanUpFunc) cleanup = 0,
294 void* clientData = 0 );
295 /* The operator new for arrays, identical to the above. */
296 #endif /* GC_OPERATOR_NEW_ARRAY */
298 /****************************************************************************
300 Inline implementation
302 ****************************************************************************/
304 #ifdef GC_NAMESPACE
305 namespace boehmgc
307 #endif
309 inline void* gc::operator new( size_t size ) {
310 return GC_MALLOC( size );
313 inline void* gc::operator new( size_t size, GCPlacement gcp ) {
314 if (gcp == UseGC)
315 return GC_MALLOC( size );
316 else if (gcp == PointerFreeGC)
317 return GC_MALLOC_ATOMIC( size );
318 else
319 return GC_MALLOC_UNCOLLECTABLE( size );
322 inline void* gc::operator new( size_t /* size */, void *p ) {
323 return p;
326 inline void gc::operator delete( void* obj ) {
327 GC_FREE( obj );
330 #ifdef GC_PLACEMENT_DELETE
331 inline void gc::operator delete( void*, void* ) {}
333 inline void gc::operator delete( void* p, GCPlacement /* gcp */ ) {
334 GC_FREE(p);
336 #endif
338 #ifdef GC_OPERATOR_NEW_ARRAY
339 inline void* gc::operator new[]( size_t size ) {
340 return gc::operator new( size );
343 inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
344 return gc::operator new( size, gcp );
347 inline void* gc::operator new[]( size_t /* size */, void *p ) {
348 return p;
351 inline void gc::operator delete[]( void* obj ) {
352 gc::operator delete( obj );
355 # ifdef GC_PLACEMENT_DELETE
356 inline void gc::operator delete[]( void*, void* ) {}
358 inline void gc::operator delete[]( void* p, GCPlacement /* gcp */ ) {
359 gc::operator delete(p);
361 # endif
362 #endif /* GC_OPERATOR_NEW_ARRAY */
364 inline gc_cleanup::~gc_cleanup() {
365 GC_register_finalizer_ignore_self( GC_base(this), 0, 0, 0, 0 );
368 inline void GC_CALLBACK gc_cleanup::cleanup( void* obj, void* displ ) {
369 ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();
372 inline gc_cleanup::gc_cleanup() {
373 GC_finalization_proc oldProc;
374 void* oldData;
375 void* base = GC_base( (void *) this );
376 if (0 != base) {
377 // Don't call the debug version, since this is a real base address.
378 GC_register_finalizer_ignore_self( base, (GC_finalization_proc)cleanup,
379 (void*)((char*)this - (char*)base),
380 &oldProc, &oldData );
381 if (0 != oldProc) {
382 GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );
387 #ifdef GC_NAMESPACE
389 #endif
391 inline void* operator new( size_t size, GC_NS_QUALIFY(GCPlacement) gcp,
392 GC_NS_QUALIFY(GCCleanUpFunc) cleanup,
393 void* clientData )
395 void* obj;
397 if (gcp == GC_NS_QUALIFY(UseGC)) {
398 obj = GC_MALLOC( size );
399 if (cleanup != 0)
400 GC_REGISTER_FINALIZER_IGNORE_SELF( obj, cleanup, clientData,
401 0, 0 );
402 } else if (gcp == GC_NS_QUALIFY(PointerFreeGC)) {
403 obj = GC_MALLOC_ATOMIC( size );
404 } else {
405 obj = GC_MALLOC_UNCOLLECTABLE( size );
407 return obj;
410 #ifdef GC_PLACEMENT_DELETE
411 inline void operator delete( void *p, GC_NS_QUALIFY(GCPlacement) /* gcp */,
412 GC_NS_QUALIFY(GCCleanUpFunc) /* cleanup */,
413 void* /* clientData */ )
415 GC_FREE(p);
417 #endif /* GC_PLACEMENT_DELETE */
419 #ifdef GC_OPERATOR_NEW_ARRAY
420 inline void* operator new[]( size_t size, GC_NS_QUALIFY(GCPlacement) gcp,
421 GC_NS_QUALIFY(GCCleanUpFunc) cleanup,
422 void* clientData )
424 return ::operator new( size, gcp, cleanup, clientData );
426 #endif /* GC_OPERATOR_NEW_ARRAY */
428 #if defined(__CYGWIN__)
429 # include <new> // for delete throw()
430 inline void operator delete(void *p)
432 GC_FREE(p);
434 #endif
436 #endif /* GC_CPP_H */