Annotation of parser3/src/include/pa_memory.h, revision 1.17
1.2 paf 1: /** @file
2: Parser: memory reference counting classes decls.
3:
1.17 ! misha 4: Copyright (c) 2001-2009 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.17 ! misha 12: static const char * const IDENT_MEMORY_H="$Date: 2007/05/07 09:47:07 $";
1.2 paf 13:
14: // include
15:
16: #include "pa_config_includes.h"
17: #include "gc.h"
18:
19: // defines
20:
1.17 ! misha 21: // use destructors for Array, Hash and VMethodFrame
! 22: #define USE_DESTRUCTORS
! 23:
1.2 paf 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:
1.10 paf 62: size_t size=known_length+1;
63: if(char *result=static_cast<char*>(pa_gc_malloc_atomic(size))) {
1.9 paf 64: memcpy(result, auto_variable_never_null, known_length);
1.2 paf 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:
1.16 misha 83: //{@ these operators can be used from stl. to be on a safe side, assume that data may contain pointers
84: inline void *operator new[] (size_t size) {
85: return pa_malloc(size);
86: }
87: inline void *operator new(size_t size) {
88: return pa_malloc(size);
89: }
1.2 paf 90: //}@
91:
92: #define UseGC ((int)1)
93: #define PointerFreeGC (true)
94:
95: //{@ Array-oriented
1.3 paf 96: inline void *operator new[] (size_t size, int) { // UseGC
1.2 paf 97: return pa_malloc(size);
98: }
99: inline void *operator new[] (size_t size, bool) { // PointerFreeGC
100: return pa_malloc_atomic(size);
101: }
102: inline void operator delete[] (void *ptr) {
103: pa_free(ptr);
104: }
105: //}@
106:
107: //{@ Structure-oriented
108: inline void *operator new (size_t size, int) { // UseGC
109: return pa_malloc(size);
110: }
111: inline void *operator new (size_t size, bool) { // PointerFreeGC
112: return pa_malloc_atomic(size);
113: }
114: inline void operator delete(void *ptr) {
115: pa_free(ptr);
116: }
117: //}@
118:
119: /// memory allocation/dallocation goes via pa_malloc/pa_free.
120: class PA_Allocated {
121: public:
122: /// the sole: instances allocated using our functions
123: static void *operator new(size_t size) {
124: return pa_malloc(size);
125: }
126: static void operator delete(void *ptr) {
127: pa_free(ptr);
128: }
129: static void *malloc(size_t size) {
130: return pa_malloc(size);
131: }
132: static void *malloc_atomic(size_t size) {
133: return pa_malloc_atomic(size);
134: }
135: static char *strdup(const char* auto_variable_never_null, size_t helper_length=0) {
136: return pa_strdup(auto_variable_never_null, helper_length);
137: }
138: static void free(void *ptr) {
139: pa_free(ptr);
140: }
141: static void *realloc(void *ptr, size_t size) {
142: return pa_realloc(ptr, size);
143: }
144:
145: private: // disabled from accidental use
146:
147: /// use malloc/malloc_atomic instead [GC clears result of those]
148: static void *calloc(size_t size);
149:
150: };
151:
152: /// Those who want their destructor called during finalization, must derive from this class [also]
153: class PA_Cleaned {
154: #ifndef PA_DEBUG_DISABLE_GC
155: static void cleanup( void* obj, void* displ ) {
156: ((PA_Cleaned*) ((char*) obj + (ptrdiff_t) displ))->~PA_Cleaned();
157: }
158:
159: public:
160: PA_Cleaned() {
161: GC_finalization_proc oldProc;
162: void* oldData;
163: void* base = GC_base( (void *) this );
164: if (0 != base) {
165: // Don't call the debug version, since this is a real base address.
166: GC_register_finalizer_ignore_self(
167: base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base),
168: &oldProc, &oldData );
169: if (0 != oldProc) {
170: GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );
171: }
172: }
173: }
174:
175: virtual ~PA_Cleaned() {
176: GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );
177: }
178: #endif
179: };
180:
181: /// Base for all Parser classes
182: typedef PA_Allocated PA_Object;
183:
184: // defines
185:
186: #define override
187: #define rethrow throw
188:
189:
190: #endif
E-mail: