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