Macaulay2 Engine
Loading...
Searching...
No Matches
newdelete.hpp
Go to the documentation of this file.
1#ifndef NEWDELETE_H
2#define NEWDELETE_H 1
3
48
49#include "interface/m2-mem.h" // for freemem, getmem, outofmem2
50//#include "debug.h" // for TRAPCHK, TRAPCHK_SIZE
51
52#include "M2/gc-include.h" // for GC_base, NULL, size_t, GC_REGISTER_FINALI...
53// IWYU pragma: begin_exports
54#include <gc/gc_allocator.h>
55// IWYU pragma: end_exports
56#include <vector>
57
58// #ifdef MEMDEBUG
59// #include <memdebug.h>
60// #endif
61
75template <typename T>
76using gc_vector = typename std::vector<T, gc_allocator<T>>;
77// TODO: eventually replace all uses of VECTOR(T) with gc_vector<T>
78#define VECTOR(T) gc_vector<T>
79
80// these replace all uses of the construction "new T[n]" (unless constructors
81// have to be run!):
82#define newarray(T, len) reinterpret_cast<T *>(getmem((len) * sizeof(T)))
83#define newarray_clear(T, len) \
84 reinterpret_cast<T *>(getmem_clear((len) * sizeof(T)))
85// this replaces all uses of the construction "new T":
86#define newitem(T) reinterpret_cast<T *>(getmem(sizeof(T)))
87#define newitem_clear(T) reinterpret_cast<T *>(getmem_clear(sizeof(T)))
88
89// this replaces all uses of the construction "new T[n]", with T containing NO
90// pointers
91#define newarray_atomic(T, len) \
92 reinterpret_cast<T *>(getmem_atomic((len) * sizeof(T)))
93#define newarray_atomic_clear(T, len) \
94 reinterpret_cast<T *>(getmem_atomic_clear((len) * sizeof(T)))
95// this replaces all uses of the construction "new T":
96#define newitem_atomic(T) reinterpret_cast<T *>(getmem_atomic(sizeof(T)))
97
98// This is used instead of newitem(T) when the size is not known to the c++
99// compiler
100// Caution: this uses the pointer type, not the struct type.
101#define GETMEM(T, size) reinterpret_cast<T>(getmem(size))
102#define GETMEM_ATOMIC(T, size) reinterpret_cast<T>(getmem_atomic(size))
103
105// This allocates POD objects onto the stack. They are then removed automatically
106// when exiting the enclosing function. This does NOT zero the corresponding memory.
107// Example uses:
108// int* exp = ARRAY_ON_STACK(int, n);
109// auto exp = ARRAY_ON_STACK(int, n);
110// In gcc or clang, we could instead use:
111// int[n] exp;
112// But that doesn't appear to be standard c++...
113#define ARRAY_ON_STACK(type, nelems) static_cast<type*>(alloca(nelems * sizeof(type)))
114
116{
117 static inline void *operator new(size_t size)
118 {
119 TRAPCHK_SIZE(size);
120 void *p = getmem(size);
121 if (p == NULL) outofmem2(size);
122 TRAPCHK(p);
123 return p;
124 }
125 static inline void *operator new[](size_t size)
126 {
127 TRAPCHK_SIZE(size);
128 void *p = getmem(size);
129 if (p == NULL) outofmem2(size);
130 TRAPCHK(p);
131 return p;
132 }
133
134 static inline void operator delete(void *obj)
135 {
136 TRAPCHK(obj);
137 if (obj != NULL) freemem(obj);
138 }
139 static inline void operator delete[](void *obj)
140 {
141 TRAPCHK(obj);
142 if (obj != NULL) freemem(obj);
143 }
144
145 static inline void *operator new(size_t size, void *existing_memory)
146 {
147 (void) size;
148 return existing_memory;
149 }
150 static inline void *operator new[](size_t size, void *existing_memory)
151 {
152 (void) size;
153 return existing_memory;
154 }
155
156 static inline void operator delete(void *obj, void *existing_memory)
157 {
158 (void) existing_memory;
159 TRAPCHK(obj);
160 }
161 static inline void operator delete[](void *obj, void *existing_memory)
162 {
163 (void) existing_memory;
164 TRAPCHK(obj);
165 }
166
167
168#if !defined(__GNUC__) || defined(__INTEL_COMPILER)
169// see Scott Meyers, Effective C++, item 14! This avoids something really bad
170// in the c++ standard.
171// ... but it slows down destructors in every class inheriting from this one
172// gnu cc does it right, running all the destructors, so we don't bother with
173// this.
174#if 0
175 // But this will put a pointer to the table of virtual methods at the start of every instance,
176 // and we don't want that, because we want to pass these pointers to C routines.
177 // So we can't have any virtual methods here.
178 virtual ~our_new_delete() {}
179#endif
180#endif
181};
182
183
185{
186public:
189 {
190 if (0 == GC_base(this)) return; // Non-heap object.
191#ifdef MEMDEBUG
192 GC_REGISTER_FINALIZER_IGNORE_SELF(M2_debug_to_outer((void*)this), 0, 0, 0, 0);
193#else
194 GC_REGISTER_FINALIZER_IGNORE_SELF(this, 0, 0, 0, 0);
195#endif
196 }
197};
198
199static inline void cleanup(void* obj, void* displ)
200{
201 (void) displ;
202#ifdef MEMDEBUG
203 obj = M2_debug_to_inner(obj);
204#endif
205 ((our_gc_cleanup*) obj) -> ~our_gc_cleanup();
206}
207
209{
210 if (0 == GC_base(this)) return; // Non-heap object.
211#ifdef MEMDEBUG
212 GC_REGISTER_FINALIZER_IGNORE_SELF(M2_debug_to_outer(this), (GC_finalization_proc) cleanup, 0, 0, 0);
213#else
214 GC_REGISTER_FINALIZER_IGNORE_SELF(this, (GC_finalization_proc) cleanup, 0, 0, 0);
215#endif
216}
217
218#endif
219
220// Local Variables:
221// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
222// indent-tabs-mode: nil
223// End:
virtual ~our_gc_cleanup()
int p
void freemem(void *s)
Definition m2-mem.cpp:103
char * getmem(size_t n)
Definition m2-mem.cpp:74
void outofmem2(size_t newsize)
Definition m2-mem.cpp:64
#define TRAPCHK_SIZE(n)
Definition m2-mem.h:67
#define TRAPCHK(p)
Definition m2-mem.h:66
Engine-wide GC allocator surface (getmem / getmem_atomic) and debug-allocation trap.
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
Definition newdelete.hpp:76
static void cleanup(void *obj, void *displ)