Annotation of parser3/src/include/pa_memory.h, revision 1.3

1.2       paf         1: /** @file
                      2:        Parser: memory reference counting classes decls.
                      3: 
                      4:        Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
                      5: 
                      6:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
                      7: */
                      8: 
                      9: #ifndef PA_MEMORY_H
                     10: #define PA_MEMORY_H
                     11: 
1.3     ! paf        12: static const char* IDENT_MEMORY_H="$Date: 2003/07/24 11:31:21 $";
1.2       paf        13: 
                     14: // include
                     15: 
                     16: #include "pa_config_includes.h"
                     17: 
                     18: #include "gc.h"
                     19: 
                     20: 
                     21: #ifdef XML
                     22: #      include "gdome.h"
                     23: // for xmlChar
                     24: #      include "libxml/tree.h"
                     25: #endif
                     26: 
                     27: // defines
                     28: 
                     29: //#define PA_DEBUG_GC_MEMORY
                     30: 
                     31: #ifdef PA_DEBUG_GC_MEMORY
                     32: void* pa_gc_malloc(size_t size);
                     33: void* pa_gc_malloc_atomic(size_t size);
                     34: void* pa_gc_realloc(void* ptr, size_t size);
                     35: void pa_gc_free(void* ptr);
                     36: 
                     37: #      define PA_GC_MALLOC(size) pa_gc_malloc(size)
                     38: #      define PA_GC_MALLOC_ATOMIC(size) pa_gc_malloc_atomic(size)
                     39: #      define PA_GC_REALLOC(ptr,size) pa_gc_realloc(ptr,size)
                     40: #      define PA_GC_FREE(ptr) pa_gc_free(ptr)
                     41: #else
                     42: inline void* pa_gc_malloc(size_t size) { return GC_MALLOC(size); }
                     43: inline void* pa_gc_malloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
                     44: inline void* pa_gc_realloc(void* ptr, size_t size) { return GC_REALLOC(ptr, size); }
                     45: inline void pa_gc_free(void* ptr) { GC_FREE(ptr); }
                     46: 
                     47: #      define PA_GC_MALLOC(size) pa_gc_malloc(size)
                     48: #      define PA_GC_MALLOC_ATOMIC(size) pa_gc_malloc_atomic(size)
                     49: #      define PA_GC_REALLOC(ptr,size) pa_gc_realloc(ptr,size)
                     50: #      define PA_GC_FREE(ptr) pa_gc_free(ptr)
                     51: #endif
                     52: 
                     53: 
                     54: // forwards
                     55: 
                     56: void *pa_fail_alloc(const char* what, size_t size);
                     57: 
                     58: // inlines
                     59: 
                     60: inline void *pa_malloc(size_t size) {
                     61:        if(void *result=PA_GC_MALLOC(size))
                     62:                return result;
                     63: 
                     64:        return pa_fail_alloc("allocate", size);
                     65: }
                     66: 
                     67: inline void *pa_malloc_atomic(size_t size) {
                     68:        if(void *result=PA_GC_MALLOC_ATOMIC(size))
                     69:                return result;
                     70: 
                     71:        return pa_fail_alloc("allocate clean", size);
                     72: }
                     73: /// @a length may be null, which mean "autocalc it"
                     74: inline char *pa_strdup(const char* auto_variable_never_null, size_t helper_length=0) {
                     75:        size_t known_length=(helper_length?helper_length:strlen(auto_variable_never_null));
                     76: 
                     77:        size_t size=known_length+1;
                     78:        if(char *result=static_cast<char*>(PA_GC_MALLOC_ATOMIC(size))) {
                     79:                memcpy(result, auto_variable_never_null, size);
                     80:                result[known_length]=0;
                     81:                return result;
                     82:        }
                     83: 
                     84:        return static_cast<char*>(pa_fail_alloc("allocate clean", size));
                     85: }
                     86: 
                     87: inline void pa_free(void *ptr) {
                     88:        PA_GC_FREE(ptr);
                     89: }
                     90: 
                     91: inline void *pa_realloc(void *ptr, size_t size) {
                     92:        if(void *result=PA_GC_REALLOC(ptr, size))
                     93:                return result;
                     94: 
                     95:        return pa_fail_alloc("reallocate to", size);
                     96: }
                     97: 
                     98: //{@ these operators are disabled, one should explicitely specify either new(UseGC) or new(PointerFreeGC)
1.3     ! paf        99: inline void *operator new(size_t) { abort(); } // disabled
        !           100: inline void *operator new[] (size_t) { abort(); } // disabled
1.2       paf       101: //}@
                    102: 
                    103: #define UseGC ((int)1)
                    104: #define PointerFreeGC (true)
                    105: 
                    106: //{@ Array-oriented
1.3     ! paf       107: inline void *operator new[] (size_t size, int) { // UseGC
1.2       paf       108:        return pa_malloc(size);
                    109: }
                    110: inline void *operator new[] (size_t size, bool) { // PointerFreeGC
                    111:        return pa_malloc_atomic(size);
                    112: }
                    113: inline void operator delete[] (void *ptr) {
                    114:        pa_free(ptr);
                    115: }
                    116: //}@
                    117: 
                    118: //{@ Structure-oriented
                    119: inline void *operator new (size_t size, int) { // UseGC
                    120:        return pa_malloc(size);
                    121: }
                    122: inline void *operator new (size_t size, bool) { // PointerFreeGC
                    123:        return pa_malloc_atomic(size);
                    124: }
                    125: inline void operator delete(void *ptr) {
                    126:        pa_free(ptr);
                    127: }
                    128: //}@
                    129: 
                    130: /// memory allocation/dallocation goes via pa_malloc/pa_free.
                    131: class PA_Allocated {
                    132: public:
                    133:        /// the sole: instances allocated using our functions
                    134:        static void *operator new(size_t size) { 
                    135:                return pa_malloc(size);
                    136:        }
                    137:        static void operator delete(void *ptr) {
                    138:                pa_free(ptr);
                    139:        }
                    140:        static void *malloc(size_t size) {
                    141:                return pa_malloc(size);
                    142:        }
                    143:        static void *malloc_atomic(size_t size) {
                    144:                return pa_malloc_atomic(size);
                    145:        }
                    146:        static char *strdup(const char* auto_variable_never_null, size_t helper_length=0) {
                    147:                return pa_strdup(auto_variable_never_null, helper_length);
                    148:        }
                    149:        static void free(void *ptr) {
                    150:                pa_free(ptr);
                    151:        }
                    152:        static void *realloc(void *ptr, size_t size) {
                    153:                return pa_realloc(ptr, size);
                    154:        }
                    155: 
                    156: private: // disabled from accidental use
                    157: 
                    158:        /// use malloc/malloc_atomic instead [GC clears result of those]
                    159:        static void *calloc(size_t size);
                    160: 
                    161: };
                    162: 
                    163: /// Those who want their destructor called during finalization, must derive from this class [also]
                    164: class PA_Cleaned {
                    165: #ifndef PA_DEBUG_DISABLE_GC
                    166:        static void cleanup( void* obj, void* displ ) {
                    167:            ((PA_Cleaned*) ((char*) obj + (ptrdiff_t) displ))->~PA_Cleaned();
                    168:        }
                    169: 
                    170: public:
                    171:        PA_Cleaned() {
                    172:                GC_finalization_proc oldProc;
                    173:                void* oldData;
                    174:                void* base = GC_base( (void *) this );
                    175:                if (0 != base)  {
                    176:                        // Don't call the debug version, since this is a real base address.
                    177:                        GC_register_finalizer_ignore_self( 
                    178:                                base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base), 
                    179:                                &oldProc, &oldData );
                    180:                        if (0 != oldProc) {
                    181:                                GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );
                    182:                        }
                    183:                }
                    184:        }
                    185: 
                    186:        virtual ~PA_Cleaned() {
                    187:            GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );
                    188:        }
                    189: #endif
                    190: };
                    191: 
                    192: /// Base for all Parser classes
                    193: typedef PA_Allocated PA_Object;
                    194: 
                    195: // defines
                    196: 
                    197: #define override
                    198: #define rethrow throw
                    199: 
                    200: 
                    201: #endif

E-mail: