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