Stop using custom memory allocators.

Fix aliasing errors. Fixes issue 139 in trunk.
Fix build errors under OSX.
This commit is contained in:
castano 2010-10-06 02:56:35 +00:00
parent 06bf4ea960
commit df13c904b2
16 changed files with 318 additions and 339 deletions

View File

@ -503,15 +503,14 @@ 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 );
m_buffer = (T *) realloc( m_buffer, sizeof(T) * m_buffer_size );
}
}

View File

@ -10,6 +10,7 @@ SET(CORE_SRCS
DefsGnucWin32.h
DefsVcWin32.h
FileSystem.h FileSystem.cpp
# FileMonitor.h FileMonitor.cpp
Library.h Library.cpp
Memory.h Memory.cpp
Ptr.h

View File

@ -232,7 +232,7 @@ namespace nv
e->clear();
}
}
mem::free(table);
free(table);
table = NULL;
entry_count = 0;
size_mask = -1;
@ -503,7 +503,7 @@ namespace nv
new_size = nextPowerOfTwo(new_size);
HashMap<T, U, H, E> 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;
@ -528,7 +528,7 @@ namespace nv
}
// Delete our old data buffer.
mem::free(table);
free(table);
}
// Steal new_hash's data.

View File

@ -15,7 +15,9 @@ extern "C" void EF_free(void * address);
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);
@ -24,7 +26,7 @@ void * nv::mem::malloc(size_t size)
#endif
}
void * nv::mem::malloc(size_t size, const char * file, int line)
void * debug_malloc(size_t size, const char * file, int line)
{
NV_UNUSED(file);
NV_UNUSED(line);
@ -35,7 +37,7 @@ void * nv::mem::malloc(size_t size, const char * file, int line)
#endif
}
void nv::mem::free(const void * ptr)
void free(void * ptr)
{
#if USE_EFENCE
return EF_free(const_cast<void *>(ptr));
@ -44,7 +46,7 @@ void nv::mem::free(const void * ptr)
#endif
}
void * nv::mem::realloc(void * ptr, size_t size)
void * realloc(void * ptr, size_t size)
{
nvDebugCheck(ptr != NULL || size != 0); // undefined realloc behavior.
#if USE_EFENCE
@ -54,3 +56,63 @@ void * nv::mem::realloc(void * ptr, size_t size)
#endif
}
/* No need to override this unless we want line info.
void * operator new (size_t size) throw()
{
return malloc(size);
}
void operator delete (void *p) throw()
{
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

View File

@ -11,177 +11,38 @@
#include <new> // new and delete
#define NV_OVERRIDE_ALLOC 0
#if NV_OVERRIDE_ALLOC
// Custom memory allocator
namespace nv
{
namespace mem
{
extern "C" {
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 * 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);
} // mem namespace
} // nv namespace
// Override new/delete
inline void * operator new (size_t size) throw()
{
return nv::mem::malloc(size);
}
inline void operator delete (void *p) throw()
{
nv::mem::free(p);
}
inline void * operator new [] (size_t size) throw()
{
return nv::mem::malloc(size);
}
inline void operator delete [] (void * p) throw()
{
nv::mem::free(p);
}
/*
#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
#endif
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 Apples
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 <new>
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <locale>
/* 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";
}
// C++ helpers.
template <typename T> T * malloc(size_t count) {
return (T *)::malloc(sizeof(T) * count);
}
/* 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.
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.
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++;
template <typename T> T * realloc(T * ptr, size_t count) {
return (T *)::realloc(ptr, 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;
template <typename T> void free(const T * ptr) {
::free((T *)ptr);
}
}
void operator delete(void* p, const std::nothrow_t&) throw()
{
::operator delete (p);
}
/* 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 () { }
/* 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
#endif // NV_CORE_MEMORY_H

View File

@ -6,7 +6,7 @@
#include "nvcore.h"
#include "Debug.h"
#include "RefCounted.h"
namespace nv
{

View File

@ -43,7 +43,13 @@ namespace nv
virtual ~StdStream()
{
if( m_fp != NULL && m_autoclose ) {
#if NV_OS_WIN32
_fclose_nolock( m_fp );
#elif NV_OS_LINUX
fclose_unlocked( m_fp );
#else
fclose( m_fp );
#endif
}
}
@ -54,22 +60,46 @@ namespace nv
{
nvDebugCheck(m_fp != NULL);
nvDebugCheck(pos < size());
#if NV_OS_WIN32
_fseek_nolock(m_fp, pos, SEEK_SET);
#elif NV_OS_LINUX
fseek_unlocked(m_fp, pos, SEEK_SET);
#else
fseek(m_fp, pos, SEEK_SET);
#endif
}
virtual uint tell() const
{
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return _ftell_nolock(m_fp);
#elif NV_OS_LINUX
return ftell_unlocked(m_fp);
#else
return ftell(m_fp);
#endif
}
virtual uint size() const
{
nvDebugCheck(m_fp != NULL);
uint pos = ftell(m_fp);
#if NV_OS_WIN32
uint pos = _ftell_nolock(m_fp);
_fseek_nolock(m_fp, 0, SEEK_END);
uint end = ftell(m_fp);
uint end = _ftell_nolock(m_fp);
_fseek_nolock(m_fp, pos, SEEK_SET);
#elif NV_OS_LINUX
uint pos = ftell_unlocked(m_fp);
fseek_unlocked(m_fp, 0, SEEK_END);
uint end = ftell_unlocked(m_fp);
fseek_unlocked(m_fp, pos, SEEK_SET);
#else
uint pos = ftell(m_fp);
fseek(m_fp, 0, SEEK_END);
uint end = ftell(m_fp);
fseek(m_fp, pos, SEEK_SET);
#endif
return end;
}
@ -123,7 +153,19 @@ namespace nv
{
nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return (uint)_fwrite_nolock(data, 1, len, m_fp);
#elif NV_OS_LINUX
return (uint)fwrite_unlocked(data, 1, len, m_fp);
#elif NV_OS_DARWIN
// @@ No error checking, always returns len.
for (uint i = 0; i < len; i++) {
putc_unlocked(((char *)data)[i], m_fp);
}
return len;
#else
return (uint)fwrite(data, 1, len, m_fp);
#endif
}
virtual bool isLoading() const
@ -161,7 +203,20 @@ namespace nv
{
nvDebugCheck(data != NULL);
nvDebugCheck(m_fp != NULL);
#if NV_OS_WIN32
return (uint)_fread_nolock(data, 1, len, m_fp);
#elif NV_OS_LINUX
return (uint)fread_unlocked(data, 1, len, m_fp);
#elif NV_OS_DARWIN
// @@ No error checking, always returns len.
for (uint i = 0; i < len; i++) {
((char *)data)[i] = getc_unlocked(m_fp);
}
return len;
#else
return (uint)fread(data, 1, len, m_fp);
#endif
}
virtual bool isLoading() const

View File

@ -15,17 +15,17 @@ namespace
{
static char * strAlloc(uint size)
{
return static_cast<char *>(mem::malloc(size));
return static_cast<char *>(malloc(size));
}
static char * strReAlloc(char * str, uint size)
{
return static_cast<char *>(mem::realloc(str, size));
return static_cast<char *>(realloc(str, size));
}
static void strFree(const char * str)
{
return mem::free(const_cast<char *>(str));
return free(const_cast<char *>(str));
}
/*static char * strDup( const char * str )

View File

@ -314,7 +314,7 @@ namespace nv
const uint16 count = getRefCount();
setRefCount(count - 1);
if (count - 1 == 0) {
mem::free(data - 2);
free(data - 2);
data = NULL;
}
}
@ -343,7 +343,7 @@ namespace nv
void allocString(const char * str, int len)
{
const char * ptr = static_cast<const char *>(mem::malloc(2 + len + 1));
const char * ptr = static_cast<const char *>(malloc(2 + len + 1));
setData( ptr );
setRefCount( 0 );

View File

@ -138,13 +138,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<float *>(nv::mem::malloc(m_count * sizeof(float)));
m_mem = malloc<float>(m_count);
}
/// Free the image, but don't clear the members.
void FloatImage::free()
{
nv::mem::free( reinterpret_cast<void *>(m_mem) );
::free(m_mem);
m_mem = NULL;
}
@ -152,7 +152,7 @@ void FloatImage::resizeChannelCount(uint c)
{
if (m_componentNum != c) {
uint count = m_width * m_height * c;
nv::mem::realloc(m_mem, count * sizeof(float));
realloc(m_mem, count * sizeof(float));
if (c > m_componentNum) {
memset(m_mem + m_count, 0, (count - m_count) * sizeof(float));

View File

@ -42,7 +42,7 @@ void Image::allocate(uint w, uint h)
free();
m_width = w;
m_height = h;
m_data = (Color32 *)nv::mem::realloc(m_data, w * h * sizeof(Color32));
m_data = (Color32 *)realloc(m_data, w * h * sizeof(Color32));
}
bool Image::load(const char * name)
@ -80,7 +80,7 @@ void Image::unwrap()
void Image::free()
{
nv::mem::free(m_data);
::free(m_data);
m_data = NULL;
}

View File

@ -64,7 +64,7 @@ namespace nv
const Vector3 & operator=(Vector3::Arg v);
const Vector2 & xy() const;
Vector2 xy() const;
const scalar * ptr() const;
@ -104,8 +104,8 @@ namespace nv
const Vector4 & operator=(Vector4::Arg v);
const Vector2 & xy() const;
const Vector3 & xyz() const;
Vector2 xy() const;
Vector3 xyz() const;
const scalar * ptr() const;
@ -211,9 +211,9 @@ namespace nv
}
inline const Vector2 & Vector3::xy() const
inline Vector2 Vector3::xy() const
{
return *(Vector2 *)this;
return Vector2(x, y);
}
inline const scalar * Vector3::ptr() const
@ -297,14 +297,14 @@ namespace nv
return *this;
}
inline const Vector2 & Vector4::xy() const
inline Vector2 Vector4::xy() const
{
return *(Vector2 *)this;
return Vector2(x, y);
}
inline const Vector3 & Vector4::xyz() const
inline Vector3 Vector4::xyz() const
{
return *(Vector3 *)this;
return Vector3(x, y, z);
}
inline const scalar * Vector4::ptr() const

View File

@ -29,6 +29,7 @@ SET(NVTT_SRCS
OptimalCompressDXT.h
OptimalCompressDXT.cpp
SingleColorLookup.h
SingleColorLookup.cpp
CompressionOptions.h
CompressionOptions.cpp
InputOptions.h

View File

@ -186,7 +186,7 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
const uint wh = w * h;
// Allocate output scanline.
uint8 * const dst = (uint8 *)mem::malloc(pitch);
uint8 * const dst = malloc<uint8>(pitch);
for (uint y = 0; y < h; y++)
{
@ -279,5 +279,5 @@ void PixelFormatConverter::compress(nvtt::InputFormat inputFormat, nvtt::AlphaMo
outputOptions.writeData(dst, pitch);
}
mem::free(dst);
free(dst);
}

View File

@ -60,10 +60,10 @@ int main(int argc, char *argv[])
outputFileNameColor.stripExtension();
outputFileNameColor.append(".dds");
colorOutputOptions.setFileName(outputFileNameColor);
colorOutputOptions.setFileName(outputFileNameColor.str());
// Load normal map.
nvtt::TexImage normalMap;
nvtt::TexImage normalMap = context.createTexImage();
if (inputFileNameNormal != NULL) {
normalMap = context.createTexImage();
if (!normalMap.load(inputFileNameColor)) {
@ -89,7 +89,7 @@ int main(int argc, char *argv[])
outputFileNameNormal.stripExtension();
outputFileNameNormal.append(".dds");
normalOutputOptions.setFileName(outputFileNameNormal);
normalOutputOptions.setFileName(outputFileNameNormal.str());
}

View File

@ -116,7 +116,7 @@ int main(int argc, char *argv[])
}
nv::Image image;
if (!loadImage(image, input)) return 1;
if (!loadImage(image, input.str())) return 1;
nv::ImageIO::ImageMetaData metaData;
metaData.tagMap.add("Thumb::Image::Width", nv::StringBuilder().number (image.width()));
@ -143,13 +143,13 @@ int main(int argc, char *argv[])
nv::AutoPtr<nv::Image> result(fresult->createImageGammaCorrect(gamma));
result->setFormat(nv::Image::Format_ARGB);
nv::StdOutputStream stream(output);
nv::ImageIO::save(output, stream, result.ptr(), &metaData);
nv::StdOutputStream stream(output.str());
nv::ImageIO::save(output.str(), stream, result.ptr(), &metaData);
}
else
{
nv::StdOutputStream stream(output);
nv::ImageIO::save(output, stream, &image, &metaData);
nv::StdOutputStream stream(output.str());
nv::ImageIO::save(output.str(), stream, &image, &metaData);
}
return 0;