mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-23 18:24:48 +00:00
213 lines
6.9 KiB
C++
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);
|
||
|
}
|