]> git.lyx.org Git - lyx.git/blob - development/Win32/vld/src/vldheap.cpp
add Python logging lib
[lyx.git] / development / Win32 / vld / src / vldheap.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 //  $Id: vldheap.cpp,v 1.13 2006/11/18 03:12:35 dmouldin Exp $
3 //
4 //  Visual Leak Detector - Internal C++ Heap Management
5 //  Copyright (c) 2006 Dan Moulding
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2.1 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 //
21 //  See COPYING.txt for the full terms of the GNU Lesser General Public License.
22 //
23 ////////////////////////////////////////////////////////////////////////////////
24
25 #include <cassert>
26 #define VLDBUILD     // Declares that we are building Visual Leak Detector.
27 #include "ntapi.h"   // Provides access to NT APIs.
28 #include "vldheap.h" // Provides access to VLD's internal heap data structures.
29 #undef new           // Do not map "new" to VLD's new operator in this file
30
31 // Global variables.
32 vldblockheader_t *vldblocklist = NULL; // List of internally allocated blocks on VLD's private heap.
33 HANDLE            vldheap;             // VLD's private heap.
34 CRITICAL_SECTION  vldheaplock;         // Serializes access to VLD's private heap.
35
36 // Local helper functions.
37 static inline void vlddelete (void *block);
38 static inline void* vldnew (unsigned int size, const char *file, int line);
39
40 // scalar delete operator - Delete operator used to free internally used memory
41 //   back to VLD's private heap.
42 //
43 //  - block (IN): Pointer to the scalar memory block to free.
44 //
45 //  Return Value:
46 //
47 //    None.
48 //
49 void operator delete (void *block)
50 {
51     vlddelete(block);
52 }
53
54 // vector delete operator - Delete operator used to free internally used memory
55 //   back to VLD's private heap.
56 //
57 //  - block (IN): Pointer to the vector memory block to free.
58 //
59 //  Return Value:
60 //
61 //    None.
62 //
63 void operator delete [] (void *block)
64 {
65     vlddelete(block);
66 }
67
68 // scalar delete operator - Delete operator used to free memory partially
69 //   allocated by new in the event that the corresponding new operator throws
70 //   an exception.
71 //
72 //  Note: This version of the delete operator should never be called directly.
73 //    The compiler automatically generates calls to this function as needed.
74 //
75 void operator delete (void *block, const char *, int)
76 {
77     vlddelete(block);
78 }
79
80 // vector delete operator - Delete operator used to free memory partially
81 //   allocated by new in the event that the corresponding new operator throws
82 //   an exception.
83 //
84 //  Note: This version of the delete operator should never be called directly.
85 //    The compiler automatically generates calls to this function as needed.
86 //
87 void operator delete [] (void *block, const char *, int)
88 {
89     vlddelete(block);
90 }
91
92 // scalar new operator - New operator used to allocate a scalar memory block
93 //   from VLD's private heap.
94 //
95 //  - size (IN): Size of the memory block to be allocated.
96 //
97 //  - file (IN): The name of the file from which this function is being
98 //      called.
99 //
100 //  - line (IN): The line number, in the above file, at which this function is
101 //      being called.
102 //
103 //  Return Value:
104 //
105 //    If the allocation succeeds, a pointer to the allocated memory block is
106 //    returned. If the allocation fails, NULL is returned.
107 //
108 void* operator new (unsigned int size, const char *file, int line)
109 {
110     return vldnew(size, file, line);
111 }
112
113 // vector new operator - New operator used to allocate a vector memory block
114 //   from VLD's private heap.
115 //
116 //  - size (IN): Size of the memory block to be allocated.
117 //
118 //  - file (IN): The name of the file from which this function is being
119 //      called.
120 //
121 //  - line (IN): The line number, in the above file, at which this function is
122 //      being called.
123 //
124 //  Return Value:
125 //
126 //    If the allocation succeeds, a pointer to the allocated memory block is
127 //    returned. If the allocation fails, NULL is returned.
128 //
129 void* operator new [] (unsigned int size, const char *file, int line)
130 {
131     return vldnew(size, file, line);
132 }
133
134 // vlddelete - Local helper function that actually frees memory back to VLD's
135 //   private heap.
136 //
137 //  - block (IN): Pointer to a memory block being freed.
138 //
139 //  Return Value:
140 //
141 //    None.
142 //
143 void vlddelete (void *block)
144 {
145     BOOL              freed;
146     vldblockheader_t *header = VLDBLOCKHEADER((LPVOID)block);
147
148     // Unlink the block from the block list.
149     EnterCriticalSection(&vldheaplock);
150     if (header->prev) {
151         header->prev->next = header->next;
152     }
153     else {
154         vldblocklist = header->next;
155     }
156
157     if (header->next) {
158         header->next->prev = header->prev;
159     }
160     LeaveCriticalSection(&vldheaplock);
161
162     // Free the block.
163     freed = RtlFreeHeap(vldheap, 0x0, header);
164     assert(freed != FALSE);
165 }
166
167 // vldnew - Local helper function that actually allocates memory from VLD's
168 //   private heap. Prepends a header, which is used for bookeeping information
169 //   that allows VLD to detect and report internal memory leaks, to the returned
170 //   block, but the header is transparent to the caller because the returned
171 //   pointer points to the useable section of memory requested by the caller, it
172 //   does not point to the block header.
173 //
174 //  - size (IN): Size of the memory block to be allocated.
175 //
176 //  - file (IN): Name of the file that called the new operator.
177 //
178 //  - line (IN): Line, in the above file, at which the new operator was called.
179 //
180 //  Return Value:
181 //
182 //    If the memory allocation succeeds, a pointer to the allocated memory
183 //    block is returned. If the allocation fails, NULL is returned.
184 //
185 void* vldnew (unsigned int size, const char *file, int line)
186 {
187     vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(vldheap, 0x0, size + sizeof(vldblockheader_t));
188     static SIZE_T     serialnumber = 0;
189
190     if (header == NULL) {
191         // Out of memory.
192         return NULL;
193     }
194
195     // Fill in the block's header information.
196     header->file         = file;
197     header->line         = line;
198     header->serialnumber = serialnumber++;
199     header->size         = size;
200
201     // Link the block into the block list.
202     EnterCriticalSection(&vldheaplock);
203     header->next         = vldblocklist;
204     if (header->next != NULL) {
205         header->next->prev = header;
206     }
207     header->prev         = NULL;
208     vldblocklist         = header;
209     LeaveCriticalSection(&vldheaplock);
210
211     // Return a pointer to the beginning of the data section of the block.
212     return (void*)VLDBLOCKDATA(header);
213 }