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