~ubuntu-dev/wxwidgets2.6/upstream-debian

« back to all changes in this revision

Viewing changes to include/wx/memory.h

  • Committer: Daniel T Chen
  • Date: 2006-06-26 10:15:11 UTC
  • Revision ID: crimsun@ubuntu.com-20060626101511-a4436cec4c6d9b35
ImportĀ DebianĀ 2.6.3.2.1

Show diffs side-by-side

added added

removed removed

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