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