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

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: 
        !            12: static const char* IDENT_MEMORY_H="$Date: 2003/06/02 15:38:53 $";
        !            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)
        !            99: inline void *operator new(size_t size) { abort(); } // disabled
        !           100: inline void *operator new[] (size_t size) { abort(); } // disabled
        !           101: //}@
        !           102: 
        !           103: #define UseGC ((int)1)
        !           104: #define PointerFreeGC (true)
        !           105: 
        !           106: //{@ Array-oriented
        !           107: inline void *operator new[] (size_t size, int mode) { // UseGC
        !           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: