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