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