xref: /aosp_15_r20/external/lzma/CPP/Common/NewHandler.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // NewHandler.cpp
2 
3 #include "StdAfx.h"
4 
5 #include <stdlib.h>
6 
7 #include "NewHandler.h"
8 
9 // #define DEBUG_MEMORY_LEAK
10 
11 #ifndef DEBUG_MEMORY_LEAK
12 
13 #ifdef Z7_REDEFINE_OPERATOR_NEW
14 
15 /*
16 void * my_new(size_t size)
17 {
18   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
19   if (size == 0)
20     size = 1;
21   void *p = ::malloc(size);
22   if (!p)
23     throw CNewException();
24   return p;
25 }
26 
27 void my_delete(void *p) throw()
28 {
29   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
30   ::free(p);
31 }
32 
33 void * my_Realloc(void *p, size_t newSize, size_t oldSize)
34 {
35   void *newBuf = my_new(newSize);
36   if (oldSize != 0)
37     memcpy(newBuf, p, oldSize);
38   my_delete(p);
39   return newBuf;
40 }
41 */
42 
43 void *
44 #ifdef _MSC_VER
45 __cdecl
46 #endif
operator new(size_t size)47 operator new(size_t size)
48 {
49   /* by C++ specification:
50        if (size == 0), operator new(size) returns non_NULL pointer.
51      If (operator new(0) returns NULL), it's out of specification.
52        but some calling code can work correctly even in this case too. */
53   // if (size == 0) return NULL; // for debug only. don't use it
54 
55   /* malloc(0) returns non_NULL in main compilers, as we need here.
56      But specification also allows malloc(0) to return NULL.
57      So we change (size=0) to (size=1) here to get real non_NULL pointer */
58   if (size == 0)
59     size = 1;
60   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
61   // void *p = ::MyAlloc(size);  // note: MyAlloc(0) returns NULL
62   void *p = ::malloc(size);
63   if (!p)
64     throw CNewException();
65   return p;
66 }
67 
68 
69 #if defined(_MSC_VER) && _MSC_VER == 1600
70 // vs2010 has no throw() by default ?
71 #pragma warning(push)
72 #pragma warning(disable : 4986) // 'operator delete': exception specification does not match previous declaration
73 #endif
74 
75 void
76 #ifdef _MSC_VER
77 __cdecl
78 #endif
operator delete(void * p)79 operator delete(void *p) throw()
80 {
81   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
82   // MyFree(p);
83   ::free(p);
84 }
85 
86 /* we define operator delete(void *p, size_t n) because
87    vs2022 compiler uses delete(void *p, size_t n), and
88    we want to mix files from different compilers:
89      - old vc6 linker
90      - old vc6 complier
91      - new vs2022 complier
92 */
93 void
94 #ifdef _MSC_VER
95 __cdecl
96 #endif
operator delete(void * p,size_t n)97 operator delete(void *p, size_t n) throw()
98 {
99   UNUSED_VAR(n)
100   ::free(p);
101 }
102 
103 #if defined(_MSC_VER) && _MSC_VER == 1600
104 #pragma warning(pop)
105 #endif
106 
107 /*
108 void *
109 #ifdef _MSC_VER
110 __cdecl
111 #endif
112 operator new[](size_t size)
113 {
114   // void *p = ::HeapAlloc(::GetProcessHeap(), 0, size);
115   if (size == 0)
116     size = 1;
117   void *p = ::malloc(size);
118   if (!p)
119     throw CNewException();
120   return p;
121 }
122 
123 void
124 #ifdef _MSC_VER
125 __cdecl
126 #endif
127 operator delete[](void *p) throw()
128 {
129   // if (!p) return; ::HeapFree(::GetProcessHeap(), 0, p);
130   ::free(p);
131 }
132 */
133 
134 #endif
135 
136 #else
137 
138 #include <stdio.h>
139 
140 // #pragma init_seg(lib)
141 /*
142 const int kDebugSize = 1000000;
143 static void *a[kDebugSize];
144 static int g_index = 0;
145 
146 class CC
147 {
148 public:
149   CC()
150   {
151     for (int i = 0; i < kDebugSize; i++)
152       a[i] = 0;
153   }
154   ~CC()
155   {
156     printf("\nDestructor: %d\n", numAllocs);
157     for (int i = 0; i < kDebugSize; i++)
158       if (a[i] != 0)
159         return;
160   }
161 } g_CC;
162 */
163 
164 #ifdef _WIN32
165 static bool wasInit = false;
166 static CRITICAL_SECTION cs;
167 #endif
168 
169 static int numAllocs = 0;
170 
171 void *
172 #ifdef _MSC_VER
173 __cdecl
174 #endif
operator new(size_t size)175 operator new(size_t size)
176 {
177  #ifdef _WIN32
178   if (!wasInit)
179   {
180     InitializeCriticalSection(&cs);
181     wasInit = true;
182   }
183   EnterCriticalSection(&cs);
184 
185   numAllocs++;
186   int loc = numAllocs;
187   void *p = HeapAlloc(GetProcessHeap(), 0, size);
188   /*
189   if (g_index < kDebugSize)
190   {
191     a[g_index] = p;
192     g_index++;
193   }
194   */
195   printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
196   LeaveCriticalSection(&cs);
197   if (!p)
198     throw CNewException();
199   return p;
200  #else
201   numAllocs++;
202   int loc = numAllocs;
203   if (size == 0)
204     size = 1;
205   void *p = malloc(size);
206   /*
207   if (g_index < kDebugSize)
208   {
209     a[g_index] = p;
210     g_index++;
211   }
212   */
213   printf("Alloc %6d, size = %8u\n", loc, (unsigned)size);
214   if (!p)
215     throw CNewException();
216   return p;
217  #endif
218 }
219 
220 void
221 #ifdef _MSC_VER
222 __cdecl
223 #endif
operator delete(void * p)224 operator delete(void *p) throw()
225 {
226   if (!p)
227     return;
228  #ifdef _WIN32
229   EnterCriticalSection(&cs);
230   /*
231   for (int i = 0; i < g_index; i++)
232     if (a[i] == p)
233       a[i] = 0;
234   */
235   HeapFree(GetProcessHeap(), 0, p);
236   // if (numAllocs == 0) numAllocs = numAllocs; // ERROR
237   numAllocs--;
238   // if (numAllocs == 0) numAllocs = numAllocs; // OK: all objects were deleted
239   printf("Free %d\n", numAllocs);
240   LeaveCriticalSection(&cs);
241  #else
242   free(p);
243   numAllocs--;
244   printf("Free %d\n", numAllocs);
245  #endif
246 }
247 
248 void
249 #ifdef _MSC_VER
250 __cdecl
251 #endif
252 operator delete(void *p, size_t n) throw();
253 void
254 #ifdef _MSC_VER
255 __cdecl
256 #endif
operator delete(void * p,size_t n)257 operator delete(void *p, size_t n) throw()
258 {
259   UNUSED_VAR(n)
260   printf("delete_WITH_SIZE=%u, ptr = %p\n", (unsigned)n, p);
261   operator delete(p);
262 }
263 
264 /*
265 void *
266 #ifdef _MSC_VER
267 __cdecl
268 #endif
269 operator new[](size_t size)
270 {
271   printf("operator_new[] : ");
272   return operator new(size);
273 }
274 
275 void
276 #ifdef _MSC_VER
277 __cdecl
278 #endif
279 operator delete(void *p, size_t sz) throw();
280 
281 void
282 #ifdef _MSC_VER
283 __cdecl
284 #endif
285 operator delete(void *p, size_t sz) throw()
286 {
287   if (!p)
288     return;
289   printf("operator_delete_size : size=%d  : ", (unsigned)sz);
290   operator delete(p);
291 }
292 
293 void
294 #ifdef _MSC_VER
295 __cdecl
296 #endif
297 operator delete[](void *p) throw()
298 {
299   if (!p)
300     return;
301   printf("operator_delete[] : ");
302   operator delete(p);
303 }
304 
305 void
306 #ifdef _MSC_VER
307 __cdecl
308 #endif
309 operator delete[](void *p, size_t sz) throw();
310 
311 void
312 #ifdef _MSC_VER
313 __cdecl
314 #endif
315 operator delete[](void *p, size_t sz) throw()
316 {
317   if (!p)
318     return;
319   printf("operator_delete_size[] : size=%d  : ", (unsigned)sz);
320   operator delete(p);
321 }
322 */
323 
324 #endif
325 
326 /*
327 int MemErrorVC(size_t)
328 {
329   throw CNewException();
330   // return 1;
331 }
332 CNewHandlerSetter::CNewHandlerSetter()
333 {
334   // MemErrorOldVCFunction = _set_new_handler(MemErrorVC);
335 }
336 CNewHandlerSetter::~CNewHandlerSetter()
337 {
338   // _set_new_handler(MemErrorOldVCFunction);
339 }
340 */
341