#ifndef WXGC_CPP_H #define WXGC_CPP_H /**************************************************************************** MrEd interface to various garbage collectors, including the Boehm collector, SenoraGC, and MzScheme's precise collector. Copyright (c) 2004-2009 PLT Scheme Inc. ****************************************************************************/ /**************************************************************************** Based On: C++ Interface to the Boehm Collector John R. Ellis and Jesse Hull Last modified on Wed Jan 4 16:30:20 PST 1995 by ellis Copyright (c) 1994 by Xerox Corporation. All rights reserved. THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. Permission is hereby granted to use or copy this program for any purpose, provided the above notices are retained on all copies. Permission to modify the code and to distribute modified code is granted, provided the above notices are retained, and a notice that the code was modified is included with the above copyright notice. ****************************************************************************/ enum GCPlacement {UseGC, AtomicGC}; #ifdef MZ_PRECISE_GC # define WXGC_ATOMIC /* empty */ # define WXGC_PTRS /* empty */ #else # define WXGC_ATOMIC (AtomicGC) # define WXGC_PTRS (UseGC) #endif typedef void (*GCCleanUpFunc)(void* obj, void* clientData); extern "C" { void objscheme_mark_external_invalid(void *); } void GC_cleanup(void *obj, void *ignored); #include "gc.h" /******************** Special kinds of GC *********************/ #if SGC_STD_DEBUGGING # ifndef USE_SENORA_GC # define USE_SENORA_GC # endif # define USE_MEMORY_TRACING #endif #ifdef USE_SENORA_GC extern void *GC_cpp_malloc(size_t); #endif #define WX_REGISTER_GLOBAL_MEMORY #ifdef WX_REGISTER_GLOBAL_MEMORY extern "C" { # ifdef wx_msw __declspec(dllimport) # endif void scheme_register_static(void *p, long size); } # define wxREGGLOB(x) scheme_register_static((void *)&x, sizeof(x)) #else # define wxREGGLOB(x) /* empty */ #endif #ifdef MZ_PRECISE_GC extern void *GC_cpp_malloc(size_t); extern void GC_cpp_delete(class gc *); # define GC_register_finalizer_ignore_self(self, a, b, c, d) GC_set_finalizer(self, 0, 3, a, b, c, d) extern void *GC_weak_box_val(void *); #endif #define gcOBJ_TO_PTR(x) x #define gcPTR_TO_OBJ(x) x extern void *GC_malloc_accounting_shadow(long a); extern void GC_free_accounting_shadow(void *a); #ifndef START_XFORM_SKIP # ifndef MZ_PRECISE_GC # define START_XFORM_SKIP /**/ # define END_XFORM_SKIP /**/ # define GC_CAN_IGNORE /**/ # define GC_MAYBE_IGNORE_INTERIOR /**/ # define XFORM_OK_PLUS + # define XFORM_OK_MINUS - # else # ifdef GC_INTERIORABLES_NEVER_MOVE # define GC_MAYBE_IGNORE_INTERIOR GC_CAN_IGNORE # else # define GC_MAYBE_IGNORE_INTERIOR /**/ # endif # endif #endif /**** The `gc' and `gc_cleanup' class ************/ class gc { public: inline virtual ~gc(); inline void *operator new(size_t size); inline void *operator new(size_t size, GCPlacement gcp); inline void operator delete(void *obj); #ifdef _MSC_VER inline void operator delete(void *obj, GCPlacement gcp); #endif #ifdef 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); # ifdef _MSC_VER inline void operator delete[](void *obj, GCPlacement gcp); # endif #endif #ifdef MZ_PRECISE_GC /* Overridden in each subclass: */ virtual inline void gcMark(); virtual inline void gcFixup(); # ifdef COMPACT_BACKTRACE_GC virtual char *gcGetName(); # endif #endif }; class gc_cleanup : public gc { public: void *__gc_external; inline gc_cleanup(); inline gc_cleanup(int cleanup); inline virtual ~gc_cleanup(); void install_cleanup(); #ifdef MZ_PRECISE_GC inline void gcMark(); inline void gcFixup(); #endif }; #ifdef MZ_PRECISE_GC inline void gc::gcMark() { } inline void gc::gcFixup() { } inline void gc_cleanup::gcMark() { gcMARK(__gc_external); } inline void gc_cleanup::gcFixup() { gcFIXUP(__gc_external); } #endif /***** Constructors and Destructors: ******/ inline gc_cleanup::gc_cleanup(void) { __gc_external = NULL; install_cleanup(); } inline gc_cleanup::gc_cleanup(int cleanup) { __gc_external = NULL; if (cleanup) install_cleanup(); } inline gc_cleanup::~gc_cleanup(void) { if (__gc_external) objscheme_mark_external_invalid(__gc_external); GC_register_finalizer_ignore_self(gcOBJ_TO_PTR(this), 0, 0, 0, 0); } inline gc::~gc(void) { } /***** Allocators: ******/ inline void *gc::operator new(size_t size) { #if defined(USE_SENORA_GC) || defined(MZ_PRECISE_GC) return GC_cpp_malloc(size); #else return GC_malloc(size); #endif } inline void *gc::operator new(size_t size, GCPlacement gcp) { if (gcp == AtomicGC) return GC_malloc_atomic(size); #if defined(USE_SENORA_GC) || defined(MZ_PRECISE_GC) return GC_cpp_malloc(size); #else return GC_malloc(size); #endif } inline void gc::operator delete(void * /*obj*/) { } #ifdef _MSC_VER inline void gc::operator delete(void *, GCPlacement gcp) { } #endif #ifdef OPERATOR_NEW_ARRAY inline void *gc::operator new[](size_t size) { #if defined(USE_SENORA_GC) || defined(MZ_PRECISE_GC) return ::operator new(size); #else return gc::operator new(size); #endif } inline void *gc::operator new[](size_t size, GCPlacement gcp) { return gc::operator new(size, gcp); } inline void gc::operator delete[](void *obj) { gc::operator delete(obj); } # ifdef _MSC_VER inline void gc::operator delete[](void *obj, GCPlacement gcp) { gc::operator delete(obj, gcp); } # endif #endif /*************** For objects not derived from `gc' ***********************/ inline void *operator new(size_t size, GCPlacement gcp) { void *obj; if (gcp == AtomicGC) obj = GC_malloc_atomic(size); else obj = GC_malloc(size); return obj; } #ifdef OPERATOR_NEW_ARRAY inline void *operator new[](size_t size, GCPlacement gcp) { return ::operator new(size, gcp); } #endif #ifdef _MSC_VER inline void operator delete(void *, GCPlacement) { } inline void operator delete[](void *, GCPlacement) { } #endif #endif /* WXGC_CPP_H */