lyx_mirror/development/Win32/vld/src/vldheap.cpp
Peter Kümmel c0708a5c5e add leak tool for msvc 'Visual Leak Detection' 1.9f: original files
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21911 a592a061-630c-0410-9148-cb99ea01b6c8
2007-12-02 11:05:21 +00:00

213 lines
6.9 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// $Id: vldheap.cpp,v 1.13 2006/11/18 03:12:35 dmouldin Exp $
//
// Visual Leak Detector - Internal C++ Heap Management
// Copyright (c) 2006 Dan Moulding
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// See COPYING.txt for the full terms of the GNU Lesser General Public License.
//
////////////////////////////////////////////////////////////////////////////////
#include <cassert>
#define VLDBUILD // Declares that we are building Visual Leak Detector.
#include "ntapi.h" // Provides access to NT APIs.
#include "vldheap.h" // Provides access to VLD's internal heap data structures.
#undef new // Do not map "new" to VLD's new operator in this file
// Global variables.
vldblockheader_t *vldblocklist = NULL; // List of internally allocated blocks on VLD's private heap.
HANDLE vldheap; // VLD's private heap.
CRITICAL_SECTION vldheaplock; // Serializes access to VLD's private heap.
// Local helper functions.
static inline void vlddelete (void *block);
static inline void* vldnew (unsigned int size, const char *file, int line);
// scalar delete operator - Delete operator used to free internally used memory
// back to VLD's private heap.
//
// - block (IN): Pointer to the scalar memory block to free.
//
// Return Value:
//
// None.
//
void operator delete (void *block)
{
vlddelete(block);
}
// vector delete operator - Delete operator used to free internally used memory
// back to VLD's private heap.
//
// - block (IN): Pointer to the vector memory block to free.
//
// Return Value:
//
// None.
//
void operator delete [] (void *block)
{
vlddelete(block);
}
// scalar delete operator - Delete operator used to free memory partially
// allocated by new in the event that the corresponding new operator throws
// an exception.
//
// Note: This version of the delete operator should never be called directly.
// The compiler automatically generates calls to this function as needed.
//
void operator delete (void *block, const char *, int)
{
vlddelete(block);
}
// vector delete operator - Delete operator used to free memory partially
// allocated by new in the event that the corresponding new operator throws
// an exception.
//
// Note: This version of the delete operator should never be called directly.
// The compiler automatically generates calls to this function as needed.
//
void operator delete [] (void *block, const char *, int)
{
vlddelete(block);
}
// scalar new operator - New operator used to allocate a scalar memory block
// from VLD's private heap.
//
// - size (IN): Size of the memory block to be allocated.
//
// - file (IN): The name of the file from which this function is being
// called.
//
// - line (IN): The line number, in the above file, at which this function is
// being called.
//
// Return Value:
//
// If the allocation succeeds, a pointer to the allocated memory block is
// returned. If the allocation fails, NULL is returned.
//
void* operator new (unsigned int size, const char *file, int line)
{
return vldnew(size, file, line);
}
// vector new operator - New operator used to allocate a vector memory block
// from VLD's private heap.
//
// - size (IN): Size of the memory block to be allocated.
//
// - file (IN): The name of the file from which this function is being
// called.
//
// - line (IN): The line number, in the above file, at which this function is
// being called.
//
// Return Value:
//
// If the allocation succeeds, a pointer to the allocated memory block is
// returned. If the allocation fails, NULL is returned.
//
void* operator new [] (unsigned int size, const char *file, int line)
{
return vldnew(size, file, line);
}
// vlddelete - Local helper function that actually frees memory back to VLD's
// private heap.
//
// - block (IN): Pointer to a memory block being freed.
//
// Return Value:
//
// None.
//
void vlddelete (void *block)
{
BOOL freed;
vldblockheader_t *header = VLDBLOCKHEADER((LPVOID)block);
// Unlink the block from the block list.
EnterCriticalSection(&vldheaplock);
if (header->prev) {
header->prev->next = header->next;
}
else {
vldblocklist = header->next;
}
if (header->next) {
header->next->prev = header->prev;
}
LeaveCriticalSection(&vldheaplock);
// Free the block.
freed = RtlFreeHeap(vldheap, 0x0, header);
assert(freed != FALSE);
}
// vldnew - Local helper function that actually allocates memory from VLD's
// private heap. Prepends a header, which is used for bookeeping information
// that allows VLD to detect and report internal memory leaks, to the returned
// block, but the header is transparent to the caller because the returned
// pointer points to the useable section of memory requested by the caller, it
// does not point to the block header.
//
// - size (IN): Size of the memory block to be allocated.
//
// - file (IN): Name of the file that called the new operator.
//
// - line (IN): Line, in the above file, at which the new operator was called.
//
// Return Value:
//
// If the memory allocation succeeds, a pointer to the allocated memory
// block is returned. If the allocation fails, NULL is returned.
//
void* vldnew (unsigned int size, const char *file, int line)
{
vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(vldheap, 0x0, size + sizeof(vldblockheader_t));
static SIZE_T serialnumber = 0;
if (header == NULL) {
// Out of memory.
return NULL;
}
// Fill in the block's header information.
header->file = file;
header->line = line;
header->serialnumber = serialnumber++;
header->size = size;
// Link the block into the block list.
EnterCriticalSection(&vldheaplock);
header->next = vldblocklist;
if (header->next != NULL) {
header->next->prev = header;
}
header->prev = NULL;
vldblocklist = header;
LeaveCriticalSection(&vldheaplock);
// Return a pointer to the beginning of the data section of the block.
return (void*)VLDBLOCKDATA(header);
}