]> git.saurik.com Git - wxWidgets.git/blame - include/wx/memory.h
Applied patch [ 1116706 ] wxRendererGeneric::DrawComboBoxDropButton position fix
[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
aaf1bbfd 73void * operator new (size_t size, wxChar * fileName, int lineNum);
b40b0f5b 74
aaf1bbfd 75void * operator new (size_t size);
2db0bbde 76
aaf1bbfd 77void operator delete (void * buf);
c801d85f 78
5dcf05ae 79#if wxUSE_ARRAY_MEMORY_OPERATORS
aaf1bbfd
JS
80void * operator new[] (size_t size);
81
82void * operator new[] (size_t size, wxChar * fileName, int lineNum);
83
84void operator delete[] (void * buf);
201812a8 85#endif
c801d85f 86
ba14d986
VZ
87// VC++ 6.0 and MWERKS
88#if ( defined(__VISUALC__) && (__VISUALC__ >= 1200) ) || defined(__MWERKS__)
2db0bbde
JS
89inline void operator delete(void* pData, wxChar* /* fileName */, int /* lineNum */)
90{
4e32eea1 91 wxDebugFree(pData, false);
2db0bbde
JS
92}
93inline void operator delete[](void* pData, wxChar* /* fileName */, int /* lineNum */)
94{
4e32eea1 95 wxDebugFree(pData, true);
2db0bbde
JS
96}
97#endif // __VISUALC__>=1200
98#endif // wxUSE_GLOBAL_MEMORY_OPERATORS
99#endif // __WXDEBUG__
100
101//**********************************************************************************
c801d85f
KB
102
103typedef unsigned int wxMarkerType;
104
105/*
106 Define the struct which will be placed at the start of all dynamically
107 allocated memory.
108*/
109
bddd7a8d 110class WXDLLIMPEXP_BASE wxMemStruct {
c801d85f 111
bddd7a8d 112friend class WXDLLIMPEXP_BASE wxDebugContext; // access to the m_next pointer for list traversal.
c801d85f
KB
113
114public:
115public:
116 int AssertList ();
117
118 size_t RequestSize () { return m_reqSize; }
119 wxMarkerType Marker () { return m_firstMarker; }
120
121 // When an object is deleted we set the id slot to a specific value.
122 inline void SetDeleted ();
123 inline int IsDeleted ();
124
125 int Append ();
126 int Unlink ();
127
128 // Used to determine if the object is really a wxMemStruct.
129 // Not a foolproof test by any means, but better than none I hope!
130 int AssertIt ();
131
132 // Do all validation on a node.
133 int ValidateNode ();
134
135 // Check the integrity of a node and of the list, node by node.
136 int CheckBlock ();
137 int CheckAllPrevious ();
138
139 // Print a single node.
140 void PrintNode ();
141
142 // Called when the memory linking functions get an error.
143 void ErrorMsg (const char *);
144 void ErrorMsg ();
145
146 inline void *GetActualData(void) const { return m_actualData; }
147
148 void Dump(void);
149
150public:
151 // Check for underwriting. There are 2 of these checks. This one
152 // inside the struct and another right after the struct.
153 wxMarkerType m_firstMarker;
154
155 // File name and line number are from cpp.
4de6207a 156 wxChar* m_fileName;
c801d85f
KB
157 int m_lineNum;
158
159 // The amount of memory requested by the caller.
160 size_t m_reqSize;
161
162 // Used to try to verify that we really are dealing with an object
163 // of the required class. Can be 1 of 2 values these indicating a valid
164 // wxMemStruct object, or a deleted wxMemStruct object.
165 wxMarkerType m_id;
166
167 wxMemStruct * m_prev;
168 wxMemStruct * m_next;
169
170 void * m_actualData;
171 bool m_isObject;
172};
173
174
175typedef void (wxMemStruct::*PmSFV) ();
176
177
178/*
b073db94 179 Debugging class. This will only have a single instance, but it's
c801d85f
KB
180 a reasonable way to keep everything together and to make this
181 available for change if needed by someone else.
182 A lot of this stuff would be better off within the wxMemStruct class, but
b073db94 183 it's stuff which we need to access at times when there is no wxMemStruct
c801d85f
KB
184 object so we use this class instead. Think of it as a collection of
185 globals which have to do with the wxMemStruct class.
186*/
187
bddd7a8d 188class WXDLLIMPEXP_BASE wxDebugContext {
c801d85f
KB
189
190protected:
191 // Used to set alignment for markers.
192 static size_t CalcAlignment ();
193
194 // Returns the amount of padding needed after something of the given
195 // size. This is so that when we cast pointers backwards and forwards
196 // the pointer value will be valid for a wxMarkerType.
197 static size_t GetPadding (const size_t size) ;
198
199 // Traverse the list.
200 static void TraverseList (PmSFV, wxMemStruct *from = NULL);
201
c801d85f
KB
202 static int debugLevel;
203 static bool debugOn;
204
478e6b71
VZ
205 static int m_balign; // byte alignment
206 static int m_balignmask; // mask for performing byte alignment
c801d85f
KB
207public:
208 // Set a checkpoint to dump only the memory from
209 // a given point
210 static wxMemStruct *checkPoint;
211
212 wxDebugContext(void);
213 ~wxDebugContext(void);
214
c801d85f
KB
215 static int GetLevel(void) { return debugLevel; }
216 static void SetLevel(int level) { debugLevel = level; }
217
218 static bool GetDebugMode(void) { return debugOn; }
219 static void SetDebugMode(bool flag) { debugOn = flag; }
220
4e32eea1 221 static void SetCheckpoint(bool all = false);
c801d85f 222 static wxMemStruct *GetCheckpoint(void) { return checkPoint; }
2bd5bbc9 223
c801d85f
KB
224 // Calculated from the request size and any padding needed
225 // before the final marker.
226 static size_t PaddedSize (const size_t reqSize);
227
228 // Calc the total amount of space we need from the system
229 // to satisfy a caller request. This includes all padding.
230 static size_t TotSize (const size_t reqSize);
231
232 // Return valid pointers to offsets within the allocated memory.
233 static char * StructPos (const char * buf);
234 static char * MidMarkerPos (const char * buf);
235 static char * CallerMemPos (const char * buf);
236 static char * EndMarkerPos (const char * buf, const size_t size);
237
238 // Given a pointer to the start of the caller requested area
239 // return a pointer to the start of the entire alloc\'d buffer.
240 static char * StartPos (const char * caller);
241
242 // Access to the list.
243 static wxMemStruct * GetHead () { return m_head; }
244 static wxMemStruct * GetTail () { return m_tail; }
245
246 // Set the list sentinals.
247 static wxMemStruct * SetHead (wxMemStruct * st) { return (m_head = st); }
248 static wxMemStruct * SetTail (wxMemStruct * st) { return (m_tail = st); }
249
250 // If this is set then every new operation checks the validity
251 // of the all previous nodes in the list.
252 static bool GetCheckPrevious () { return m_checkPrevious; }
253 static void SetCheckPrevious (bool value) { m_checkPrevious = value; }
254
4e32eea1
WS
255 // Checks all nodes, or all nodes if checkAll is true
256 static int Check(bool checkAll = false);
c801d85f
KB
257
258 // Print out the list of wxMemStruct nodes.
259 static bool PrintList(void);
260
261 // Dump objects
262 static bool Dump(void);
263
264 // Print statistics
4e32eea1 265 static bool PrintStatistics(bool detailed = true);
c801d85f
KB
266
267 // Print out the classes in the application.
268 static bool PrintClasses(void);
269
270 // Count the number of non-wxDebugContext-related objects
271 // that are outstanding
4e32eea1 272 static int CountObjectsLeft(bool sinceCheckpoint = false);
c801d85f 273
ced55544
VS
274 // This function is used to output the dump
275 static void OutputDumpLine(const wxChar *szFormat, ...);
276
c801d85f
KB
277private:
278 // Store these here to allow access to the list without
279 // needing to have a wxMemStruct object.
280 static wxMemStruct* m_head;
281 static wxMemStruct* m_tail;
282
4e32eea1
WS
283 // Set to false if we're not checking all previous nodes when
284 // we do a new. Set to true when we are.
c801d85f
KB
285 static bool m_checkPrevious;
286};
287
ced55544
VS
288// Final cleanup (e.g. deleting the log object and doing memory leak checking)
289// will be delayed until all wxDebugContextDumpDelayCounter objects have been
290// destructed. Adding one wxDebugContextDumpDelayCounter per file will delay
291// memory leak checking until after destructing all global objects.
292class WXDLLIMPEXP_BASE wxDebugContextDumpDelayCounter
293{
294public:
295 wxDebugContextDumpDelayCounter() {
296 sm_count++;
297 }
298
299 ~wxDebugContextDumpDelayCounter() {
300 sm_count--;
301 if(!sm_count) DoDump();
302 }
303private:
304 void DoDump();
305 static int sm_count;
306};
307
308// make leak dump after all globals have been destructed
309static wxDebugContextDumpDelayCounter wxDebugContextDumpDelayCounter_File;
310#define WXDEBUG_DUMPDELAYCOUNTER \
311 static wxDebugContextDumpDelayCounter wxDebugContextDumpDelayCounter_Extra;
312
6b037754 313// Output a debug message, in a system dependent fashion.
bddd7a8d
VZ
314void WXDLLIMPEXP_BASE wxTrace(const wxChar *fmt ...) ATTRIBUTE_PRINTF_1;
315void WXDLLIMPEXP_BASE wxTraceLevel(int level, const wxChar *fmt ...) ATTRIBUTE_PRINTF_2;
c801d85f
KB
316
317#define WXTRACE wxTrace
318#define WXTRACELEVEL wxTraceLevel
319
ced55544
VS
320#else // (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
321
322#define WXDEBUG_DUMPDELAYCOUNTER
c801d85f 323
f2e5c082
VZ
324// Borland C++ Builder 6 seems to have troubles with inline functions (see bug
325// 819700)
326#if 0
327 inline void wxTrace(const wxChar *WXUNUSED(fmt)) {}
328 inline void wxTraceLevel(int WXUNUSED(level), const wxChar *WXUNUSED(fmt)) {}
329#else
330 #define wxTrace(fmt)
331 #define wxTraceLevel(l, fmt)
332#endif
c801d85f 333
4e32eea1
WS
334#define WXTRACE true ? (void)0 : wxTrace
335#define WXTRACELEVEL true ? (void)0 : wxTraceLevel
c801d85f 336
ced55544 337#endif // (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
c801d85f
KB
338
339#endif
34138703 340 // _WX_MEMORYH__
c801d85f 341