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: