aboutsummaryrefslogtreecommitdiffstats
path: root/gc/include/gc_cpp.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gc/include/gc_cpp.h114
1 files changed, 90 insertions, 24 deletions
diff --git a/gc/include/gc_cpp.h b/gc/include/gc_cpp.h
index ad7df5d..ceb73f5 100644
--- a/gc/include/gc_cpp.h
+++ b/gc/include/gc_cpp.h
@@ -16,12 +16,11 @@ the code was modified is included with the above copyright notice.
C++ Interface to the Boehm Collector
John R. Ellis and Jesse Hull
- Last modified on Mon Jul 24 15:43:42 PDT 1995 by ellis
This interface provides access to the Boehm collector. It provides
basic facilities similar to those described in "Safe, Efficient
Garbage Collection for C++", by John R. Elis and David L. Detlefs
-(ftp.parc.xerox.com:/pub/ellis/gc).
+(ftp://ftp.parc.xerox.com/pub/ellis/gc).
All heap-allocated objects are either "collectable" or
"uncollectable". Programs must explicitly delete uncollectable
@@ -38,7 +37,7 @@ Objects derived from class "gc" are collectable. For example:
A* a = new A; // a is collectable.
Collectable instances of non-class types can be allocated using the GC
-placement:
+(or UseGC) placement:
typedef int A[ 10 ];
A* a = new (GC) A;
@@ -84,7 +83,7 @@ Cautions:
1. Be sure the collector has been augmented with "make c++".
2. If your compiler supports the new "operator new[]" syntax, then
-add -DOPERATOR_NEW_ARRAY to the Makefile.
+add -DGC_OPERATOR_NEW_ARRAY to the Makefile.
If your compiler doesn't support "operator new[]", beware that an
array of type T, where T is derived from "gc", may or may not be
@@ -124,6 +123,12 @@ invoked using the ANSI-conforming syntax t->~T(). If you're using
cfront 3.0, you'll have to comment out the class gc_cleanup, which
uses explicit invocation.
+5. GC name conflicts:
+
+Many other systems seem to use the identifier "GC" as an abbreviation
+for "Graphics Context". Since version 5.0, GC placement has been replaced
+by UseGC. GC is an alias for UseGC, unless GC_NAME_CONFLICT is defined.
+
****************************************************************************/
#include "gc.h"
@@ -132,24 +137,35 @@ uses explicit invocation.
#define _cdecl
#endif
-#if ! defined( OPERATOR_NEW_ARRAY ) \
- && (__BORLANDC__ >= 0x450 || (__GNUC__ >= 2 && __GNUC_MINOR__ >= 6) \
- || __WATCOMC__ >= 1050)
-# define OPERATOR_NEW_ARRAY
+#if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \
+ && !defined(_ENABLE_ARRAYNEW) /* Digimars */ \
+ && (defined(__BORLANDC__) && (__BORLANDC__ < 0x450) \
+ || (defined(__GNUC__) && \
+ (__GNUC__ < 2 || __GNUC__ == 2 && __GNUC_MINOR__ < 6)) \
+ || (defined(__WATCOMC__) && __WATCOMC__ < 1050))
+# define GC_NO_OPERATOR_NEW_ARRAY
#endif
-enum GCPlacement {GC, NoGC, PointerFreeGC};
+#if !defined(GC_NO_OPERATOR_NEW_ARRAY) && !defined(GC_OPERATOR_NEW_ARRAY)
+# define GC_OPERATOR_NEW_ARRAY
+#endif
+
+enum GCPlacement {UseGC,
+#ifndef GC_NAME_CONFLICT
+ GC=UseGC,
+#endif
+ NoGC, PointerFreeGC};
class gc {public:
inline void* operator new( size_t size );
inline void* operator new( size_t size, GCPlacement gcp );
inline void operator delete( void* obj );
-#ifdef OPERATOR_NEW_ARRAY
+#ifdef GC_OPERATOR_NEW_ARRAY
inline void* operator new[]( size_t size );
inline void* operator new[]( size_t size, GCPlacement gcp );
inline void operator delete[]( void* obj );
-#endif /* OPERATOR_NEW_ARRAY */
+#endif /* GC_OPERATOR_NEW_ARRAY */
};
/*
Instances of classes derived from "gc" will be allocated in the
@@ -170,6 +186,12 @@ private:
extern "C" {typedef void (*GCCleanUpFunc)( void* obj, void* clientData );}
+#ifdef _MSC_VER
+ // Disable warning that "no matching operator delete found; memory will
+ // not be freed if initialization throws an exception"
+# pragma warning(disable:4291)
+#endif
+
inline void* operator new(
size_t size,
GCPlacement gcp,
@@ -189,7 +211,50 @@ inline void* operator new(
classes derived from "gc_cleanup" or containing members derived
from "gc_cleanup". */
-#ifdef OPERATOR_NEW_ARRAY
+#ifdef GC_OPERATOR_NEW_ARRAY
+
+#ifdef _MSC_VER
+ /** This ensures that the system default operator new[] doesn't get
+ * undefined, which is what seems to happen on VC++ 6 for some reason
+ * if we define a multi-argument operator new[].
+ * There seems to be really redirect new in this environment without
+ * including this everywhere.
+ */
+ inline void *operator new[]( size_t size )
+ {
+ return GC_MALLOC_UNCOLLECTABLE( size );
+ }
+
+ inline void operator delete[](void* obj)
+ {
+ GC_FREE(obj);
+ };
+
+ inline void* operator new( size_t size)
+ {
+ return GC_MALLOC_UNCOLLECTABLE( size);
+ };
+
+ inline void operator delete(void* obj)
+ {
+ GC_FREE(obj);
+ };
+
+
+// This new operator is used by VC++ in case of Debug builds !
+ inline void* operator new( size_t size,
+ int ,//nBlockUse,
+ const char * szFileName,
+ int nLine
+ ) {
+# ifndef GC_DEBUG
+ return GC_malloc_uncollectable( size );
+# else
+ return GC_debug_malloc_uncollectable(size, szFileName, nLine);
+# endif
+ }
+
+#endif /* _MSC_VER */
inline void* operator new[](
size_t size,
@@ -199,7 +264,7 @@ inline void* operator new[](
/*
The operator new for arrays, identical to the above. */
-#endif /* OPERATOR_NEW_ARRAY */
+#endif /* GC_OPERATOR_NEW_ARRAY */
/****************************************************************************
@@ -211,7 +276,7 @@ inline void* gc::operator new( size_t size ) {
return GC_MALLOC( size );}
inline void* gc::operator new( size_t size, GCPlacement gcp ) {
- if (gcp == GC)
+ if (gcp == UseGC)
return GC_MALLOC( size );
else if (gcp == PointerFreeGC)
return GC_MALLOC_ATOMIC( size );
@@ -222,7 +287,7 @@ inline void gc::operator delete( void* obj ) {
GC_FREE( obj );}
-#ifdef OPERATOR_NEW_ARRAY
+#ifdef GC_OPERATOR_NEW_ARRAY
inline void* gc::operator new[]( size_t size ) {
return gc::operator new( size );}
@@ -233,7 +298,7 @@ inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
inline void gc::operator delete[]( void* obj ) {
gc::operator delete( obj );}
-#endif /* OPERATOR_NEW_ARRAY */
+#endif /* GC_OPERATOR_NEW_ARRAY */
inline gc_cleanup::~gc_cleanup() {
@@ -246,12 +311,13 @@ inline gc_cleanup::gc_cleanup() {
GC_finalization_proc oldProc;
void* oldData;
void* base = GC_base( (void *) this );
- if (0 == base) return;
- GC_REGISTER_FINALIZER_IGNORE_SELF(
- base, cleanup, (void*) ((char*) this - (char*) base),
+ if (0 != base) {
+ // Don't call the debug version, since this is a real base address.
+ GC_register_finalizer_ignore_self(
+ base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base),
&oldProc, &oldData );
- if (0 != oldProc) {
- GC_REGISTER_FINALIZER_IGNORE_SELF( base, oldProc, oldData, 0, 0 );}}
+ if (0 != oldProc) {
+ GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );}}}
inline void* operator new(
size_t size,
@@ -261,7 +327,7 @@ inline void* operator new(
{
void* obj;
- if (gcp == GC) {
+ if (gcp == UseGC) {
obj = GC_MALLOC( size );
if (cleanup != 0)
GC_REGISTER_FINALIZER_IGNORE_SELF(
@@ -273,7 +339,7 @@ inline void* operator new(
return obj;}
-#ifdef OPERATOR_NEW_ARRAY
+#ifdef GC_OPERATOR_NEW_ARRAY
inline void* operator new[](
size_t size,
@@ -283,7 +349,7 @@ inline void* operator new[](
{
return ::operator new( size, gcp, cleanup, clientData );}
-#endif /* OPERATOR_NEW_ARRAY */
+#endif /* GC_OPERATOR_NEW_ARRAY */
#endif /* GC_CPP_H */