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

1.2       paf         1: /** @file
                      2:        Parser: memory reference counting classes decls.
                      3: 
1.18      moko        4:        Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)
1.2       paf         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.19    ! moko       12: #define IDENT_PA_MEMORY_H "$Id: pa_memory.h,v 1.18 2012/03/16 09:24:09 moko Exp $"
1.2       paf        13: 
                     14: // include
                     15: 
                     16: #include "pa_config_includes.h"
                     17: #include "gc.h"
                     18: 
1.19    ! moko       19: // define destructors use for Array, Hash and VMethodFrame
1.17      misha      20: #define USE_DESTRUCTORS
                     21: 
1.2       paf        22: inline void* pa_gc_malloc(size_t size) { return GC_MALLOC(size); }
                     23: inline void* pa_gc_malloc_atomic(size_t size) { return GC_MALLOC_ATOMIC(size); }
                     24: inline void* pa_gc_realloc(void* ptr, size_t size) { return GC_REALLOC(ptr, size); }
                     25: inline void pa_gc_free(void* ptr) { GC_FREE(ptr); }
                     26: 
                     27: // forwards
                     28: 
                     29: void *pa_fail_alloc(const char* what, size_t size);
                     30: 
                     31: // inlines
                     32: 
                     33: inline void *pa_malloc(size_t size) {
1.4       paf        34:        if(void *result=pa_gc_malloc(size))
1.2       paf        35:                return result;
                     36: 
                     37:        return pa_fail_alloc("allocate", size);
                     38: }
                     39: 
                     40: inline void *pa_malloc_atomic(size_t size) {
1.4       paf        41:        if(void *result=pa_gc_malloc_atomic(size))
1.2       paf        42:                return result;
                     43: 
                     44:        return pa_fail_alloc("allocate clean", size);
                     45: }
                     46: /// @a length may be null, which mean "autocalc it"
                     47: inline char *pa_strdup(const char* auto_variable_never_null, size_t helper_length=0) {
                     48:        size_t known_length=(helper_length?helper_length:strlen(auto_variable_never_null));
                     49: 
1.10      paf        50:        size_t size=known_length+1;
                     51:        if(char *result=static_cast<char*>(pa_gc_malloc_atomic(size))) {
1.9       paf        52:                memcpy(result, auto_variable_never_null, known_length);
1.2       paf        53:                result[known_length]=0;
                     54:                return result;
                     55:        }
                     56: 
                     57:        return static_cast<char*>(pa_fail_alloc("allocate clean", size));
                     58: }
                     59: 
                     60: inline void pa_free(void *ptr) {
1.4       paf        61:        pa_gc_free(ptr);
1.2       paf        62: }
                     63: 
                     64: inline void *pa_realloc(void *ptr, size_t size) {
1.4       paf        65:        if(void *result=pa_gc_realloc(ptr, size))
1.2       paf        66:                return result;
                     67: 
                     68:        return pa_fail_alloc("reallocate to", size);
                     69: }
                     70: 
1.16      misha      71: //{@ these operators can be used from stl. to be on a safe side, assume that data may contain pointers
                     72: inline void *operator new[] (size_t size) {
                     73:        return pa_malloc(size);
                     74: }
                     75: inline void *operator new(size_t size) {
                     76:        return pa_malloc(size);
                     77: }
1.2       paf        78: //}@
                     79: 
                     80: #define UseGC ((int)1)
                     81: #define PointerFreeGC (true)
                     82: 
                     83: //{@ Array-oriented
1.3       paf        84: inline void *operator new[] (size_t size, int) { // UseGC
1.2       paf        85:        return pa_malloc(size);
                     86: }
                     87: inline void *operator new[] (size_t size, bool) { // PointerFreeGC
                     88:        return pa_malloc_atomic(size);
                     89: }
                     90: inline void operator delete[] (void *ptr) {
                     91:        pa_free(ptr);
                     92: }
                     93: //}@
                     94: 
                     95: //{@ Structure-oriented
                     96: inline void *operator new (size_t size, int) { // UseGC
                     97:        return pa_malloc(size);
                     98: }
                     99: inline void *operator new (size_t size, bool) { // PointerFreeGC
                    100:        return pa_malloc_atomic(size);
                    101: }
                    102: inline void operator delete(void *ptr) {
                    103:        pa_free(ptr);
                    104: }
                    105: //}@
                    106: 
                    107: /// memory allocation/dallocation goes via pa_malloc/pa_free.
                    108: class PA_Allocated {
                    109: public:
                    110:        /// the sole: instances allocated using our functions
                    111:        static void *operator new(size_t size) { 
                    112:                return pa_malloc(size);
                    113:        }
                    114:        static void operator delete(void *ptr) {
                    115:                pa_free(ptr);
                    116:        }
                    117:        static void *malloc(size_t size) {
                    118:                return pa_malloc(size);
                    119:        }
                    120:        static void *malloc_atomic(size_t size) {
                    121:                return pa_malloc_atomic(size);
                    122:        }
                    123:        static char *strdup(const char* auto_variable_never_null, size_t helper_length=0) {
                    124:                return pa_strdup(auto_variable_never_null, helper_length);
                    125:        }
                    126:        static void free(void *ptr) {
                    127:                pa_free(ptr);
                    128:        }
                    129:        static void *realloc(void *ptr, size_t size) {
                    130:                return pa_realloc(ptr, size);
                    131:        }
                    132: 
                    133: private: // disabled from accidental use
                    134: 
                    135:        /// use malloc/malloc_atomic instead [GC clears result of those]
                    136:        static void *calloc(size_t size);
                    137: 
                    138: };
                    139: 
                    140: /// Those who want their destructor called during finalization, must derive from this class [also]
                    141: class PA_Cleaned {
                    142: #ifndef PA_DEBUG_DISABLE_GC
                    143:        static void cleanup( void* obj, void* displ ) {
                    144:            ((PA_Cleaned*) ((char*) obj + (ptrdiff_t) displ))->~PA_Cleaned();
                    145:        }
                    146: 
                    147: public:
                    148:        PA_Cleaned() {
                    149:                GC_finalization_proc oldProc;
                    150:                void* oldData;
                    151:                void* base = GC_base( (void *) this );
                    152:                if (0 != base)  {
                    153:                        // Don't call the debug version, since this is a real base address.
                    154:                        GC_register_finalizer_ignore_self( 
                    155:                                base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base), 
                    156:                                &oldProc, &oldData );
                    157:                        if (0 != oldProc) {
                    158:                                GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );
                    159:                        }
                    160:                }
                    161:        }
                    162: 
                    163:        virtual ~PA_Cleaned() {
                    164:            GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );
                    165:        }
                    166: #endif
                    167: };
                    168: 
                    169: /// Base for all Parser classes
                    170: typedef PA_Allocated PA_Object;
                    171: 
                    172: // defines
                    173: 
                    174: #define override
                    175: #define rethrow throw
                    176: 
                    177: 
                    178: #endif

E-mail: