]> git.saurik.com Git - wxWidgets.git/blame - include/wx/memory.h
wxURL - doc cleanups, depreciated more methods, more source comments. wxURI - enclos...
[wxWidgets.git] / include / wx / memory.h
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: memory.h
3// Purpose: MDI classes
4// Author: Arthur Seaton, Julian Smart
5// Modified by:
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Julian Smart
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
34138703
JS
12#ifndef _WX_MEMORYH__
13#define _WX_MEMORYH__
c801d85f 14
12028905 15#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
c801d85f
KB
16#pragma interface "memory.h"
17#endif
18
19#include "wx/defs.h"
2432b92d 20#include "wx/string.h"
ced55544 21#include "wx/msgout.h"
c801d85f
KB
22
23/*
24 The macro which will be expanded to include the file and line number
25 info, or to be a straight call to the new operator.
26*/
27
ea57084d 28#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
c801d85f
KB
29
30#include <stddef.h>
31
ea57084d 32#ifdef __WXDEBUG__
e55ad60e 33
4e32eea1
WS
34WXDLLIMPEXP_BASE void * wxDebugAlloc(size_t size, wxChar * fileName, int lineNum, bool isObject, bool isVect = false);
35WXDLLIMPEXP_BASE void wxDebugFree(void * buf, bool isVect = false);
2db0bbde
JS
36
37//**********************************************************************************
38/*
39 The global operator new used for everything apart from getting
40 dynamic storage within this function itself.
41*/
42
43// We'll only do malloc and free for the moment: leave the interesting
44// stuff for the wxObject versions.
45// devik 2000-8-29: All new/delete ops are now inline because they can't
46// be marked as dllexport/dllimport. It then leads to weird bugs when
47// used on MSW as DLL
c801d85f 48
47d67540 49#if wxUSE_GLOBAL_MEMORY_OPERATORS
c801d85f 50
6b037754
JS
51// Undefine temporarily (new is #defined in object.h) because we want to
52// declare some new operators.
c801d85f 53#ifdef new
3f4a0c5b 54 #undef new
c801d85f
KB
55#endif
56
5dcf05ae 57#if defined(__SUNCC__)
3f4a0c5b
VZ
58 #define wxUSE_ARRAY_MEMORY_OPERATORS 0
59#elif !( defined (__VISUALC__) && (__VISUALC__ <= 1020) ) || defined( __MWERKS__)
60 #define wxUSE_ARRAY_MEMORY_OPERATORS 1
ba6f401d
VZ
61#elif defined (__SGI_CC_)
62 // only supported by -n32 compilers
63 #ifndef __EDG_ABI_COMPATIBILITY_VERSION
64 #define wxUSE_ARRAY_MEMORY_OPERATORS 0
65 #endif
2db0bbde
JS
66#elif !( defined (__VISUALC__) && (__VISUALC__ <= 1020) ) || defined( __MWERKS__)
67 #define wxUSE_ARRAY_MEMORY_OPERATORS 1
5dcf05ae 68#else
ba6f401d 69 // ::operator new[] is a recent C++ feature, so assume it's not supported
3f4a0c5b 70 #define wxUSE_ARRAY_MEMORY_OPERATORS 0
5dcf05ae
JS
71#endif
72
2db0bbde
JS
73inline void * operator new (size_t size, wxChar * fileName, int lineNum)
74{
4e32eea1 75 return wxDebugAlloc(size, fileName, lineNum, false, false);
2db0bbde 76}
b40b0f5b 77
2db0bbde
JS
78inline void * operator new (size_t size)
79{
4e32eea1 80 return wxDebugAlloc(size, NULL, 0, false);
2db0bbde
JS
81}
82
83inline void operator delete (void * buf)
84{
4e32eea1 85 wxDebugFree(buf, false);
2db0bbde 86}
c801d85f 87
5dcf05ae 88#if wxUSE_ARRAY_MEMORY_OPERATORS
2db0bbde
JS
89inline void * operator new[] (size_t size)
90{
4e32eea1 91 return wxDebugAlloc(size, NULL, 0, false, true);
2db0bbde
JS
92}
93
94inline void * operator new[] (size_t size, wxChar * fileName, int lineNum)
95{
4e32eea1 96 return wxDebugAlloc(size, fileName, lineNum, false, true);
2db0bbde
JS
97}
98
99inline void operator delete[] (void * buf)
100{
4e32eea1 101 wxDebugFree(buf, true);
2db0bbde 102}
201812a8 103#endif
c801d85f 104
ba14d986
VZ
105// VC++ 6.0 and MWERKS
106#if ( defined(__VISUALC__) && (__VISUALC__ >= 1200) ) || defined(__MWERKS__)
2db0bbde
JS
107inline void operator delete(void* pData, wxChar* /* fileName */, int /* lineNum */)
108{
4e32eea1 109 wxDebugFree(pData, false);
2db0bbde
JS
110}
111inline void operator delete[](void* pData, wxChar* /* fileName */, int /* lineNum */)
112{
4e32eea1 113 wxDebugFree(pData, true);
2db0bbde
JS
114}
115#endif // __VISUALC__>=1200
116#endif // wxUSE_GLOBAL_MEMORY_OPERATORS
117#endif // __WXDEBUG__
118
119//**********************************************************************************
c801d85f
KB
120
121typedef unsigned int wxMarkerType;
122
123/*
124 Define the struct which will be placed at the start of all dynamically
125 allocated memory.
126*/
127
bddd7a8d 128class WXDLLIMPEXP_BASE wxMemStruct {
c801d85f 129
bddd7a8d 130friend class WXDLLIMPEXP_BASE wxDebugContext; // access to the m_next pointer for list traversal.
c801d85f
KB
131
132public:
133public:
134 int AssertList ();
135
136 size_t RequestSize () { return m_reqSize; }
137 wxMarkerType Marker () { return m_firstMarker; }
138
139 // When an object is deleted we set the id slot to a specific value.
140 inline void SetDeleted ();
141 inline int IsDeleted ();
142
143 int Append ();
144 int Unlink ();
145
146 // Used to determine if the object is really a wxMemStruct.
147 // Not a foolproof test by any means, but better than none I hope!
148 int AssertIt ();
149
150 // Do all validation on a node.
151 int ValidateNode ();
152
153 // Check the integrity of a node and of the list, node by node.
154 int CheckBlock ();
155 int CheckAllPrevious ();
156
157 // Print a single node.
158 void PrintNode ();
159
160 // Called when the memory linking functions get an error.
161 void ErrorMsg (const char *);
162 void ErrorMsg ();
163
164 inline void *GetActualData(void) const { return m_actualData; }
165
166 void Dump(void);
167
168public:
169 // Check for underwriting. There are 2 of these checks. This one
170 // inside the struct and another right after the struct.
171 wxMarkerType m_firstMarker;
172
173 // File name and line number are from cpp.
4de6207a 174 wxChar* m_fileName;
c801d85f
KB
175 int m_lineNum;
176
177 // The amount of memory requested by the caller.
178 size_t m_reqSize;
179
180 // Used to try to verify that we really are dealing with an object
181 // of the required class. Can be 1 of 2 values these indicating a valid
182 // wxMemStruct object, or a deleted wxMemStruct object.
183 wxMarkerType m_id;
184
185 wxMemStruct * m_prev;
186 wxMemStruct * m_next;
187
188 void * m_actualData;
189 bool m_isObject;
190};
191
192
193typedef void (wxMemStruct::*PmSFV) ();
194
195
196/*
b073db94 197 Debugging class. This will only have a single instance, but it's
c801d85f
KB
198 a reasonable way to keep everything together and to make this
199 available for change if needed by someone else.
200 A lot of this stuff would be better off within the wxMemStruct class, but
b073db94 201 it's stuff which we need to access at times when there is no wxMemStruct
c801d85f
KB
202 object so we use this class instead. Think of it as a collection of
203 globals which have to do with the wxMemStruct class.
204*/
205
bddd7a8d 206class WXDLLIMPEXP_BASE wxDebugContext {
c801d85f
KB
207
208protected:
209 // Used to set alignment for markers.
210 static size_t CalcAlignment ();
211
212 // Returns the amount of padding needed after something of the given
213 // size. This is so that when we cast pointers backwards and forwards
214 // the pointer value will be valid for a wxMarkerType.
215 static size_t GetPadding (const size_t size) ;
216
217 // Traverse the list.
218 static void TraverseList (PmSFV, wxMemStruct *from = NULL);
219
c801d85f
KB
220 static int debugLevel;
221 static bool debugOn;
222
478e6b71
VZ
223 static int m_balign; // byte alignment
224 static int m_balignmask; // mask for performing byte alignment
c801d85f
KB
225public:
226 // Set a checkpoint to dump only the memory from
227 // a given point
228 static wxMemStruct *checkPoint;
229
230 wxDebugContext(void);
231 ~wxDebugContext(void);
232
c801d85f
KB
233 static int GetLevel(void) { return debugLevel; }
234 static void SetLevel(int level) { debugLevel = level; }
235
236 static bool GetDebugMode(void) { return debugOn; }
237 static void SetDebugMode(bool flag) { debugOn = flag; }
238
4e32eea1 239 static void SetCheckpoint(bool all = false);
c801d85f 240 static wxMemStruct *GetCheckpoint(void) { return checkPoint; }
2bd5bbc9 241
c801d85f
KB
242 // Calculated from the request size and any padding needed
243 // before the final marker.
244 static size_t PaddedSize (const size_t reqSize);
245
246 // Calc the total amount of space we need from the system
247 // to satisfy a caller request. This includes all padding.
248 static size_t TotSize (const size_t reqSize);
249
250 // Return valid pointers to offsets within the allocated memory.
251 static char * StructPos (const char * buf);
252 static char * MidMarkerPos (const char * buf);
253 static char * CallerMemPos (const char * buf);
254 static char * EndMarkerPos (const char * buf, const size_t size);
255
256 // Given a pointer to the start of the caller requested area
257 // return a pointer to the start of the entire alloc\'d buffer.
258 static char * StartPos (const char * caller);
259
260 // Access to the list.
261 static wxMemStruct * GetHead () { return m_head; }
262 static wxMemStruct * GetTail () { return m_tail; }
263
264 // Set the list sentinals.
265 static wxMemStruct * SetHead (wxMemStruct * st) { return (m_head = st); }
266 static wxMemStruct * SetTail (wxMemStruct * st) { return (m_tail = st); }
267
268 // If this is set then every new operation checks the validity
269 // of the all previous nodes in the list.
270 static bool GetCheckPrevious () { return m_checkPrevious; }
271 static void SetCheckPrevious (bool value) { m_checkPrevious = value; }
272
4e32eea1
WS
273 // Checks all nodes, or all nodes if checkAll is true
274 static int Check(bool checkAll = false);
c801d85f
KB
275
276 // Print out the list of wxMemStruct nodes.
277 static bool PrintList(void);
278
279 // Dump objects
280 static bool Dump(void);
281
282 // Print statistics
4e32eea1 283 static bool PrintStatistics(bool detailed = true);
c801d85f
KB
284
285 // Print out the classes in the application.
286 static bool PrintClasses(void);
287
288 // Count the number of non-wxDebugContext-related objects
289 // that are outstanding
4e32eea1 290 static int CountObjectsLeft(bool sinceCheckpoint = false);
c801d85f 291
ced55544
VS
292 // This function is used to output the dump
293 static void OutputDumpLine(const wxChar *szFormat, ...);
294
c801d85f
KB
295private:
296 // Store these here to allow access to the list without
297 // needing to have a wxMemStruct object.
298 static wxMemStruct* m_head;
299 static wxMemStruct* m_tail;
300
4e32eea1
WS
301 // Set to false if we're not checking all previous nodes when
302 // we do a new. Set to true when we are.
c801d85f
KB
303 static bool m_checkPrevious;
304};
305
ced55544
VS
306// Final cleanup (e.g. deleting the log object and doing memory leak checking)
307// will be delayed until all wxDebugContextDumpDelayCounter objects have been
308// destructed. Adding one wxDebugContextDumpDelayCounter per file will delay
309// memory leak checking until after destructing all global objects.
310class WXDLLIMPEXP_BASE wxDebugContextDumpDelayCounter
311{
312public:
313 wxDebugContextDumpDelayCounter() {
314 sm_count++;
315 }
316
317 ~wxDebugContextDumpDelayCounter() {
318 sm_count--;
319 if(!sm_count) DoDump();
320 }
321private:
322 void DoDump();
323 static int sm_count;
324};
325
326// make leak dump after all globals have been destructed
327static wxDebugContextDumpDelayCounter wxDebugContextDumpDelayCounter_File;
328#define WXDEBUG_DUMPDELAYCOUNTER \
329 static wxDebugContextDumpDelayCounter wxDebugContextDumpDelayCounter_Extra;
330
6b037754 331// Output a debug message, in a system dependent fashion.
bddd7a8d
VZ
332void WXDLLIMPEXP_BASE wxTrace(const wxChar *fmt ...) ATTRIBUTE_PRINTF_1;
333void WXDLLIMPEXP_BASE wxTraceLevel(int level, const wxChar *fmt ...) ATTRIBUTE_PRINTF_2;
c801d85f
KB
334
335#define WXTRACE wxTrace
336#define WXTRACELEVEL wxTraceLevel
337
ced55544
VS
338#else // (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
339
340#define WXDEBUG_DUMPDELAYCOUNTER
c801d85f 341
f2e5c082
VZ
342// Borland C++ Builder 6 seems to have troubles with inline functions (see bug
343// 819700)
344#if 0
345 inline void wxTrace(const wxChar *WXUNUSED(fmt)) {}
346 inline void wxTraceLevel(int WXUNUSED(level), const wxChar *WXUNUSED(fmt)) {}
347#else
348 #define wxTrace(fmt)
349 #define wxTraceLevel(l, fmt)
350#endif
c801d85f 351
4e32eea1
WS
352#define WXTRACE true ? (void)0 : wxTrace
353#define WXTRACELEVEL true ? (void)0 : wxTraceLevel
c801d85f 354
ced55544 355#endif // (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
c801d85f
KB
356
357#endif
34138703 358 // _WX_MEMORYH__
c801d85f 359