Free Electron
memory.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2015 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __platform_memory_h__
8 #define __platform_memory_h__
9 
10 #if FE_OS==FE_WIN32 || FE_OS==FE_WIN64
11 //#define FE_EXPORT_MEM_VIA_FUNC
12 #else
13 #define FE_EXPORT_MEM_VIA_FUNC
14 #endif
15 //#define FE_MEM_RAWTEST
16 
17 #if FE_CODEGEN<=FE_DEBUG
18 #define FE_CHECK_NEW TRUE
19 #else
20 #define FE_CHECK_NEW FALSE
21 #endif
22 
23 //* HACK something with amd64, multi-processor, or a bug causes malloc on stack
24 //* or maybe multi-threaded stacks can reside on either side of the heap
25 #ifdef __x86_64__
26 #define FE_HEAP_CHECKABLE FALSE
27 #else
28 #define FE_HEAP_CHECKABLE FE_CHECK_NEW
29 #endif
30 
31 // isn't required to be the same as FE_CHECK_NEW
32 #if FE_CODEGEN<=FE_DEBUG
33 #define FE_CHECK_HEAP FE_HEAP_CHECKABLE
34 #else
35 #define FE_CHECK_HEAP FALSE
36 #endif
37 
38 #define FE_LOCK_MEMORY (FE_CHECK_HEAP || FE_CHECK_NEW)
39 
40 #if FE_SSE!=0
41 #define FE_MEM_ALIGNMENT 16
42 #else
43 #define FE_MEM_ALIGNMENT 0
44 #endif
45 
46 #if FE_OS==FE_WIN32 || FE_OS==FE_WIN64 || defined(__clang__)
47 #define FE_SAFE_COUNTED_MUTEX FALSE
48 #else
49 #define FE_SAFE_COUNTED_MUTEX TRUE
50 #endif
51 
52 namespace fe
53 {
54 
55 extern "C"
56 {
57 
58 typedef void* ( FE_CDECL allocateFunction )( FE_UWORD byteCount );
59 typedef void ( FE_CDECL deallocateFunction )( void* pMemory );
60 typedef void* ( FE_CDECL reallocateFunction )( void* pMemory, FE_UWORD byteCount );
61 
62 } /* extern "C" */
63 
64 #if FE_COMPILER==FE_DMC
65 extern allocateFunction* gs_pAllocateFunction;
66 extern deallocateFunction* gs_pDeallocateFunction;
67 extern reallocateFunction* gs_pReallocateFunction;
68 extern void* gs_pHeapBase;
69 extern I32 gs_newCheck;
70 #else
71 FE_MEM_PORT extern allocateFunction* gs_pAllocateFunction;
72 FE_MEM_PORT extern deallocateFunction* gs_pDeallocateFunction;
73 FE_MEM_PORT extern reallocateFunction* gs_pReallocateFunction;
74 FE_MEM_PORT extern void* gs_pHeapBase;
75 FE_MEM_PORT extern I32 gs_newCheck;
76 #endif
77 
78 FE_MEM_PORT void * FE_CDECL ex_allocate(FE_UWORD byteCount);
79 FE_MEM_PORT void * FE_CDECL ex_reallocate(void *pMemory, FE_UWORD byteCount);
80 FE_MEM_PORT void FE_CDECL ex_deallocate(void *pMemory);
81 
82 extern "C"
83 {
84 
85 inline
86 void* allocate( FE_UWORD byteCount )
87 {
88 #ifdef FE_MEM_RAWTEST
89  return malloc(byteCount);
90 #endif
91 #ifdef FE_EXPORT_MEM_VIA_FUNC
92  return ex_allocate(byteCount);
93 #else
94  return gs_pAllocateFunction( byteCount );
95 #endif
96 }
97 
98 
99 inline
100 void deallocate( void* pMemory )
101 {
102 // assert( gs_pDeallocateFunction );
103 #ifdef FE_MEM_RAWTEST
104  free(pMemory);
105  return;
106 #endif
107 
108 #ifdef FE_EXPORT_MEM_VIA_FUNC
109  ex_deallocate(pMemory);
110 #else
111  gs_pDeallocateFunction( pMemory );
112 #endif
113 }
114 
115 inline
116 void* reallocate( void* pMemory, FE_UWORD byteCount )
117 {
118 #ifdef FE_MEM_RAWTEST
119  return realloc(pMemory, byteCount);
120 #endif
121 #ifdef FE_EXPORT_MEM_VIA_FUNC
122  return ex_reallocate(pMemory, byteCount);
123 #else
124  return gs_pReallocateFunction( pMemory, byteCount );
125 #endif
126 }
127 
128 } /* extern "C" */
129 
130 /** @brief Basic memory management
131  */
132 class Memory
133 {
134  public:
135 static bool isHeap(void* pPtr);
136 static bool isHeapOrCannotTell(void* pPtr);
137 static bool newWorks(void);
138 
139 #if FE_LOCK_MEMORY
140 #if FE_SAFE_COUNTED_MUTEX
141 static I32 ms_mutexCount;
142 static RecursiveMutex* ms_pMutex;
143 #else
144 static RecursiveMutex ms_mutex;
145 #endif
146 #endif
147 };
148 
149 #if !FE_CHECK_HEAP
150 inline bool Memory::isHeap(void* pPtr)
151 {
152  return false;
153 }
154 #elif FE_OS==FE_LINUX
155 inline bool Memory::isHeap(void* pPtr)
156 {
157  U8 current_stack;
158 // printf("Memory::isHeap %p<%p\n",pPtr,(void*)&current_stack);
159  return pPtr < (void*)&current_stack;
160 }
161 #elif FE_OS==FE_WIN32 || FE_OS==FE_WIN64
162 inline bool Memory::isHeap(void* pPtr)
163 {
164 /* TODO try
165  HANDLE heap=GetProcessHeap();
166  return HeapValidate(heap,0x0,pPtr);
167 */
168 
169  // what was wrong with this one?
170 // return _CrtIsValidHeapPointer(pPtr);
171 
172  // not 64-bit compatible
173  return pPtr >= gs_pHeapBase;
174 }
175 #elif FE_OS==FE_OSX
176 inline bool Memory::isHeap(void* pPtr)
177 {
178  U8 current_stack;
179 // printf("Memory::isHeap %p<%p\n",pPtr,(void*)&current_stack);
180  return pPtr < (void*)&current_stack;
181 }
182 #else
183 #error Memory::isHeap not implemented
184 #endif
185 
186 inline bool Memory::newWorks(void)
187 {
188 #if FE_CHECK_NEW
189  if(!gs_newCheck)
190  {
191  char* byte=new char();
192  delete byte;
193  gs_newCheck=gs_pHeapBase? 1: -1;
194  }
195  return gs_newCheck>0;
196 #else
197  return false;
198 #endif
199 }
200 
201 inline bool Memory::isHeapOrCannotTell(void* pPtr)
202 {
203 #if FE_CHECK_HEAP
204  return !newWorks() || Memory::isHeap(pPtr);
205 #else
206  return true;
207 #endif
208 }
209 
210 FE_DL_EXPORT void FE_CDECL setAllocateFunction(allocateFunction *p_fn);
211 FE_DL_EXPORT void FE_CDECL setDeallocateFunction(deallocateFunction *p_fn);
212 
213 } /* namespace */
214 
215 #if FALSE
216 inline void* _cdecl operator new( size_t byteCount )
217 { return fe::allocate( byteCount ); }
218 inline void* _cdecl operator new[]( size_t byteCount )
219 { return operator new( byteCount ); }
220 
221 inline void _cdecl operator delete( void* pMemory )
222 { fe::deallocate( pMemory ); }
223 inline void _cdecl operator delete[]( void* pMemory )
224 { operator delete( pMemory ); }
225 #endif
226 
227 //* NOTE ISO C++1z does not allow dynamic exception specifications
228 #if (FE_COMPILER==FE_GNU && __GNUC__>6) || (defined(__clang__) && __cplusplus >= 201703L)
229 #define FE_NO_DYNAMIC_EXCEPTIONS 1
230 #else
231 #define FE_NO_DYNAMIC_EXCEPTIONS 0
232 #endif
233 
234 #ifndef FE_USE_HOST_NEW
235 #if !defined(__clang__)
236 void* FE_CDECL operator new( size_t byteCount );
237 void* FE_CDECL operator new[]( size_t byteCount );
238 void FE_CDECL operator delete( void* pMemory );
239 void FE_CDECL operator delete[]( void* pMemory );
240 #elif __cplusplus >= 201703L
241 void* FE_CDECL operator new( size_t byteCount ) noexcept(false);
242 void* FE_CDECL operator new[]( size_t byteCount ) noexcept(false);
243 void FE_CDECL operator delete( void* pMemory ) throw ();
244 void FE_CDECL operator delete[]( void* pMemory ) throw ();
245 #else
246 void* FE_CDECL operator new( size_t byteCount ) throw (std::bad_alloc);
247 void* FE_CDECL operator new[]( size_t byteCount ) throw (std::bad_alloc);
248 void FE_CDECL operator delete( void* pMemory ) throw ();
249 void FE_CDECL operator delete[]( void* pMemory ) throw ();
250 #endif
251 #endif
252 
253 #endif /* __platform_memory_h__ */
254 
kernel
Definition: namespace.dox:3
Basic memory management.
Definition: memory.h:132