From f33bcfafaddef2095d3c699a297c144b599c271d Mon Sep 17 00:00:00 2001 From: castano Date: Thu, 28 Oct 2010 04:25:23 +0000 Subject: [PATCH] Remove malloc overrides. Fixes issue 138. --- src/nvcore/Containers.h | 18 +-- src/nvcore/Memory.cpp | 112 +++++++++++++++--- src/nvcore/Memory.h | 186 +++++------------------------- src/nvcore/StrLib.cpp | 6 +- src/nvcore/StrLib.h | 4 +- src/nvimage/FloatImage.cpp | 4 +- src/nvimage/Image.cpp | 2 +- src/nvimage/ImageIO.cpp | 4 +- src/nvtt/CompressRGB.cpp | 4 +- src/nvtt/cuda/CudaCompressDXT.cpp | 10 +- 10 files changed, 149 insertions(+), 201 deletions(-) diff --git a/src/nvcore/Containers.h b/src/nvcore/Containers.h index f0b63d4..3d1d8ee 100644 --- a/src/nvcore/Containers.h +++ b/src/nvcore/Containers.h @@ -16,9 +16,9 @@ Do not use memmove in insert & remove, use copy ctors instead. // nvcore -#include -#include -#include +#include "nvcore.h" +#include "Memory.h" +#include "Debug.h" #include // memmove #include // for placement new @@ -589,15 +589,15 @@ namespace nv // free the buffer. if( m_buffer_size == 0 ) { if( m_buffer ) { - mem::free( m_buffer ); + free( m_buffer ); m_buffer = NULL; } } // realloc the buffer else { - if( m_buffer ) m_buffer = (T *) mem::realloc( m_buffer, sizeof(T) * m_buffer_size ); - else m_buffer = (T *) mem::malloc( sizeof(T) * m_buffer_size ); + if( m_buffer ) m_buffer = (T *) realloc(m_buffer, sizeof(T) * m_buffer_size); + else m_buffer = (T *) ::malloc(sizeof(T) * m_buffer_size); } } @@ -778,7 +778,7 @@ namespace nv e->clear(); } } - mem::free(table); + free(table); table = NULL; entry_count = 0; size_mask = -1; @@ -1001,7 +1001,7 @@ namespace nv new_size = nextPowerOfTwo(new_size); HashMap new_hash; - new_hash.table = (Entry *) mem::malloc(sizeof(Entry) * new_size); + new_hash.table = (Entry *) ::malloc(sizeof(Entry) * new_size); nvDebugCheck(new_hash.table != NULL); new_hash.entry_count = 0; @@ -1026,7 +1026,7 @@ namespace nv } // Delete our old data buffer. - mem::free(table); + free(table); } // Steal new_hash's data. diff --git a/src/nvcore/Memory.cpp b/src/nvcore/Memory.cpp index 7ece018..d470580 100644 --- a/src/nvcore/Memory.cpp +++ b/src/nvcore/Memory.cpp @@ -1,36 +1,118 @@ +// This code is in the public domain -- Ignacio Castaño #include "Memory.h" #include "Debug.h" -//#if HAVE_MALLOC_H -//#include -//#endif - #include +#define USE_EFENCE 0 + +#if USE_EFENCE +extern "C" void *EF_malloc(size_t size); +extern "C" void *EF_realloc(void * oldBuffer, size_t newSize); +extern "C" void EF_free(void * address); +#endif using namespace nv; -void * nv::mem::malloc(size_t size) +#if NV_OVERRIDE_ALLOC + +void * malloc(size_t size) +{ +#if USE_EFENCE + return EF_malloc(size); +#else + return ::malloc(size); +#endif +} + +void * debug_malloc(size_t size, const char * file, int line) +{ + NV_UNUSED(file); + NV_UNUSED(line); +#if USE_EFENCE + return EF_malloc(size); +#else + return ::malloc(size); +#endif +} + +void free(void * ptr) { - return ::malloc(size); +#if USE_EFENCE + return EF_free(const_cast(ptr)); +#else + ::free(const_cast(ptr)); +#endif } -void * nv::mem::malloc(size_t size, const char * file, int line) +void * realloc(void * ptr, size_t size) { - NV_UNUSED(file); - NV_UNUSED(line); - return ::malloc(size); + nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior. +#if USE_EFENCE + return EF_realloc(ptr, size); +#else + return ::realloc(ptr, size); +#endif } -void nv::mem::free(const void * ptr) +/* No need to override this unless we want line info. +void * operator new (size_t size) throw() { - ::free(const_cast(ptr)); + return malloc(size); } -void * nv::mem::realloc(void * ptr, size_t size) +void operator delete (void *p) throw() { - nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior. - return ::realloc(ptr, size); + free(p); } +void * operator new [] (size_t size) throw() +{ + return malloc(size); +} + +void operator delete [] (void * p) throw() +{ + free(p); +} +*/ + +#if 0 // Code from Apple: +void* operator new(std::size_t sz) throw (std::bad_alloc) +{ + void *result = std::malloc (sz == 0 ? 1 : sz); + if (result == NULL) + throw std::bad_alloc(); + gNewCounter++; + return result; +} +void operator delete(void* p) throw() +{ + if (p == NULL) + return; + std::free (p); + gDeleteCounter++; +} + +/* These are the 'nothrow' versions of the above operators. + The system version will try to call a std::new_handler if they + fail, but your overriding versions are not required to do this. */ +void* operator new(std::size_t sz, const std::nothrow_t&) throw() +{ + try { + void * result = ::operator new (sz); // calls our overridden operator new + return result; + } catch (std::bad_alloc &) { + return NULL; + } +} +void operator delete(void* p, const std::nothrow_t&) throw() +{ + ::operator delete (p); +} + +#endif // 0 + + +#endif // NV_OVERRIDE_ALLOC diff --git a/src/nvcore/Memory.h b/src/nvcore/Memory.h index d699926..897388b 100644 --- a/src/nvcore/Memory.h +++ b/src/nvcore/Memory.h @@ -1,186 +1,52 @@ -// This code is in the public domain -- castanyo@yahoo.es +// This code is in the public domain -- Ignacio Castaño +#pragma once #ifndef NV_CORE_MEMORY_H #define NV_CORE_MEMORY_H -#include +#include "nvcore.h" #include // malloc(), realloc() and free() -#include // size_t +#include // size_t #include // new and delete -// Custom memory allocator -namespace nv -{ - namespace mem - { - NVCORE_API void * malloc(size_t size); - NVCORE_API void * malloc(size_t size, const char * file, int line); - - NVCORE_API void free(const void * ptr); - NVCORE_API void * realloc(void * ptr, size_t size); - - } // mem namespace - -} // nv namespace - - -// Override new/delete +#define NV_OVERRIDE_ALLOC 0 -inline void * operator new (size_t size) throw() -{ - return nv::mem::malloc(size); -} - -inline void operator delete (void *p) throw() -{ - nv::mem::free(p); -} +#if NV_OVERRIDE_ALLOC -inline void * operator new [] (size_t size) throw() -{ - return nv::mem::malloc(size); -} - -inline void operator delete [] (void * p) throw() -{ - nv::mem::free(p); +// Custom memory allocator +extern "C" { + NVCORE_API void * malloc(size_t size); + NVCORE_API void * debug_malloc(size_t size, const char * file, int line); + NVCORE_API void free(void * ptr); + NVCORE_API void * realloc(void * ptr, size_t size); } /* #ifdef _DEBUG #define new new(__FILE__, __LINE__) -#define malloc(i) malloc(i, __FILE__, __LINE__) +#define malloc(i) debug_malloc(i, __FILE__, __LINE__) #endif */ -#if 0 -/* - File: main.cpp - - Version: 1.0 - - Abstract: Overrides the C++ 'operator new' and 'operator delete'. - - Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. - ("Apple") in consideration of your agreement to the following terms, and your - use, installation, modification or redistribution of this Apple software - constitutes acceptance of these terms. If you do not agree with these terms, - please do not use, install, modify or redistribute this Apple software. - - In consideration of your agreement to abide by the following terms, and subject - to these terms, Apple grants you a personal, non-exclusive license, under Apple’s - copyrights in this original Apple software (the "Apple Software"), to use, - reproduce, modify and redistribute the Apple Software, with or without - modifications, in source and/or binary forms; provided that if you redistribute - the Apple Software in its entirety and without modifications, you must retain - this notice and the following text and disclaimers in all such redistributions of - the Apple Software. Neither the name, trademarks, service marks or logos of - Apple Computer, Inc. may be used to endorse or promote products derived from the - Apple Software without specific prior written permission from Apple. Except as - expressly stated in this notice, no other rights or licenses, express or implied, - are granted by Apple herein, including but not limited to any patent rights that - may be infringed by your derivative works or by other works in which the Apple - Software may be incorporated. - - The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO - WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED - WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN - COMBINATION WITH YOUR PRODUCTS. - - IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION - OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT - (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - Copyright © 2006 Apple Computer, Inc., All Rights Reserved -*/ - -/* This sample shows how to override the C++ global 'new' and 'delete' operators. */ -#include -#include -#include -#include -#include - -/* Some variables and code to make the example do something. */ -namespace { - unsigned long long gNewCounter; // number of times 'new' was called - unsigned long long gDeleteCounter; // number of times 'delete' was called - - void printCounters() // print the counters above - { - std::cout << "new was called " << gNewCounter << " times and delete was called " << gDeleteCounter << " times\n"; - } -} - -/* These are the overridden new and delete routines. - Most applications will want to override at least these four versions of new/delete if they override any of them. - - In Mac OS, it's not necessary to override the array versions of operator new and delete if all - they would do is call the non-array versions; the C++ standard library, as an extension - to the C++ standard, does this for you. +#endif - Developers should consult the section [lib.support.dynamic] in the C++ standard to see the requirements - on the generic operators new and delete; the system may expect that your overridden operators meet all these - requirements. +namespace nv { - Your operators may be called by the system, even early in start-up before constructors have been executed. */ -void* operator new(std::size_t sz) throw (std::bad_alloc) -{ - void *result = std::malloc (sz == 0 ? 1 : sz); - if (result == NULL) - throw std::bad_alloc(); - gNewCounter++; - return result; -} -void operator delete(void* p) throw() -{ - if (p == NULL) - return; - std::free (p); - gDeleteCounter++; -} + // C++ helpers. + template T * malloc(size_t count) { + return (T *)::malloc(sizeof(T) * count); + } -/* These are the 'nothrow' versions of the above operators. - The system version will try to call a std::new_handler if they - fail, but your overriding versions are not required to do this. */ -void* operator new(std::size_t sz, const std::nothrow_t&) throw() -{ - try { - void * result = ::operator new (sz); // calls our overridden operator new - return result; - } catch (std::bad_alloc &) { - return NULL; - } -} -void operator delete(void* p, const std::nothrow_t&) throw() -{ - ::operator delete (p); -} + template T * realloc(T * ptr, size_t count) { + return (T *)::realloc(ptr, sizeof(T) * count); + } -/* Bug 4067110 is that if your program has no weak symbols at all, the linker will not set the - WEAK_DEFINES bit in the Mach-O header and as a result the new and delete operators above won't - be seen by system libraries. This is mostly a problem for test programs and small examples, - since almost all real C++ programs complicated enough to override new and delete will have at - least one weak symbol. However, this is a small example, so: */ -void __attribute__((weak, visibility("default"))) workaroundFor4067110 () { } + template void free(const T * ptr) { + ::free((void *)ptr); + } -/* This is a simple test program that causes the runtime library to call new and delete. */ -int main() -{ - atexit (printCounters); - try { - std::locale example("does_not_exist"); - } catch (std::runtime_error &x) { - } - return 0; -} -#endif // 0 +} // nv namespace #endif // NV_CORE_MEMORY_H diff --git a/src/nvcore/StrLib.cpp b/src/nvcore/StrLib.cpp index 34cf992..34518d9 100644 --- a/src/nvcore/StrLib.cpp +++ b/src/nvcore/StrLib.cpp @@ -21,17 +21,17 @@ namespace { static char * strAlloc(uint size) { - return static_cast(mem::malloc(size)); + return static_cast(::malloc(size)); } static char * strReAlloc(char * str, uint size) { - return static_cast(mem::realloc(str, size)); + return static_cast(::realloc(str, size)); } static void strFree(const char * str) { - return mem::free(const_cast(str)); + return ::free(const_cast(str)); } /*static char * strDup( const char * str ) diff --git a/src/nvcore/StrLib.h b/src/nvcore/StrLib.h index 8012271..4164cf5 100644 --- a/src/nvcore/StrLib.h +++ b/src/nvcore/StrLib.h @@ -294,7 +294,7 @@ namespace nv const uint16 count = getRefCount(); setRefCount(count - 1); if (count - 1 == 0) { - mem::free(data - 2); + free(data - 2); data = NULL; } } @@ -323,7 +323,7 @@ namespace nv void allocString(const char * str, int len) { - const char * ptr = static_cast(mem::malloc(2 + len + 1)); + const char * ptr = static_cast(::malloc(2 + len + 1)); setData( ptr ); setRefCount( 0 ); diff --git a/src/nvimage/FloatImage.cpp b/src/nvimage/FloatImage.cpp index 9bf43c5..598c3c5 100644 --- a/src/nvimage/FloatImage.cpp +++ b/src/nvimage/FloatImage.cpp @@ -151,13 +151,13 @@ void FloatImage::allocate(uint c, uint w, uint h) m_height = h; m_componentNum = c; m_count = w * h * c; - m_mem = reinterpret_cast(nv::mem::malloc(m_count * sizeof(float))); + m_mem = reinterpret_cast(::malloc(m_count * sizeof(float))); } /// Free the image, but don't clear the members. void FloatImage::free() { - nv::mem::free( reinterpret_cast(m_mem) ); + ::free( reinterpret_cast(m_mem) ); m_mem = NULL; } diff --git a/src/nvimage/Image.cpp b/src/nvimage/Image.cpp index 2307d5c..53c0b5f 100644 --- a/src/nvimage/Image.cpp +++ b/src/nvimage/Image.cpp @@ -78,7 +78,7 @@ void Image::unwrap() void Image::free() { - nv::mem::free(m_data); + ::free(m_data); m_data = NULL; } diff --git a/src/nvimage/ImageIO.cpp b/src/nvimage/ImageIO.cpp index 55177cd..e1c9334 100644 --- a/src/nvimage/ImageIO.cpp +++ b/src/nvimage/ImageIO.cpp @@ -954,7 +954,7 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName, Stream & s) fimage->allocate(spp, width, height); int linesize = TIFFScanlineSize(tif); - tdata_t buf = (::uint8 *)nv::mem::malloc(linesize); + tdata_t buf = (::uint8 *)::malloc(linesize); for (uint y = 0; y < height; y++) { @@ -991,7 +991,7 @@ FloatImage * nv::ImageIO::loadFloatTIFF(const char * fileName, Stream & s) } } - nv::mem::free(buf); + ::free(buf); TIFFClose(tif); diff --git a/src/nvtt/CompressRGB.cpp b/src/nvtt/CompressRGB.cpp index a48ebd6..d7e1831 100644 --- a/src/nvtt/CompressRGB.cpp +++ b/src/nvtt/CompressRGB.cpp @@ -82,7 +82,7 @@ void nv::compressRGB(const Image * image, const OutputOptions::Private & outputO // Determine pitch. uint pitch = computePitch(w, compressionOptions.bitcount, 8); - uint8 * dst = (uint8 *)mem::malloc(pitch + 4); + uint8 * dst = (uint8 *)::malloc(pitch + 4); for (uint y = 0; y < h; y++) { @@ -127,6 +127,6 @@ void nv::compressRGB(const Image * image, const OutputOptions::Private & outputO } } - mem::free(dst); + ::free(dst); } diff --git a/src/nvtt/cuda/CudaCompressDXT.cpp b/src/nvtt/cuda/CudaCompressDXT.cpp index c59bedd..6b45ceb 100644 --- a/src/nvtt/cuda/CudaCompressDXT.cpp +++ b/src/nvtt/cuda/CudaCompressDXT.cpp @@ -137,7 +137,7 @@ void CudaCompressor::compressDXT1(const CompressionOptions::Private & compressio const uint h = (m_image->height() + 3) / 4; uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); + uint * blockLinearImage = (uint *) ::malloc(imageSize); convertToBlockLinear(m_image, blockLinearImage); // @@ Do this in parallel with the GPU, or in the GPU! const uint blockNum = w * h; @@ -207,14 +207,14 @@ void CudaCompressor::compressDXT3(const CompressionOptions::Private & compressio const uint h = (m_image->height() + 3) / 4; uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); + uint * blockLinearImage = (uint *) ::malloc(imageSize); convertToBlockLinear(m_image, blockLinearImage); const uint blockNum = w * h; const uint compressedSize = blockNum * 8; AlphaBlockDXT3 * alphaBlocks = NULL; - alphaBlocks = (AlphaBlockDXT3 *)malloc(min(compressedSize, MAX_BLOCKS * 8U)); + alphaBlocks = (AlphaBlockDXT3 *)::malloc(min(compressedSize, MAX_BLOCKS * 8U)); setupCompressKernel(compressionOptions.colorWeight.ptr()); @@ -298,14 +298,14 @@ void CudaCompressor::compressDXT5(const CompressionOptions::Private & compressio const uint h = (m_image->height() + 3) / 4; uint imageSize = w * h * 16 * sizeof(Color32); - uint * blockLinearImage = (uint *) malloc(imageSize); + uint * blockLinearImage = (uint *) ::malloc(imageSize); convertToBlockLinear(m_image, blockLinearImage); const uint blockNum = w * h; const uint compressedSize = blockNum * 8; AlphaBlockDXT5 * alphaBlocks = NULL; - alphaBlocks = (AlphaBlockDXT5 *)malloc(min(compressedSize, MAX_BLOCKS * 8U)); + alphaBlocks = (AlphaBlockDXT5 *)::malloc(min(compressedSize, MAX_BLOCKS * 8U)); setupCompressKernel(compressionOptions.colorWeight.ptr());