mirror of https://github.com/PCSX2/pcsx2.git
wxWidgets/MSW: Applied my custom string/object heap allocators to several more wxWidgets containers and types (helps reduce fragmentation and multi-threaded contention on the main heap).
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3100 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
4a2c5737c0
commit
6ec36fa37d
|
@ -13,8 +13,7 @@
|
|||
#define _WX_BUFFER_H
|
||||
|
||||
#include "wx/wxchar.h"
|
||||
|
||||
#include <stdlib.h> // malloc() and free()
|
||||
#include "wx/msw/HeapAllocator.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Special classes for (wide) character strings: they use malloc/free instead
|
||||
|
@ -31,13 +30,13 @@ public: \
|
|||
} \
|
||||
\
|
||||
classname(size_t len) \
|
||||
: m_str((chartype *)malloc((len + 1)*sizeof(chartype))) \
|
||||
: m_str((chartype *)_allocHeap_wxString((len + 1)*sizeof(chartype))) \
|
||||
{ \
|
||||
m_str[len] = (chartype)0; \
|
||||
} \
|
||||
\
|
||||
/* no need to check for NULL, free() does it */ \
|
||||
~classname() { free(m_str); } \
|
||||
~classname() { _freeHeap_wxString(m_str); } \
|
||||
\
|
||||
/* \
|
||||
WARNING: \
|
||||
|
@ -66,7 +65,7 @@ public: \
|
|||
\
|
||||
void reset() \
|
||||
{ \
|
||||
free(m_str); \
|
||||
_freeHeap_wxString(m_str); \
|
||||
m_str = NULL; \
|
||||
} \
|
||||
\
|
||||
|
@ -77,14 +76,14 @@ public: \
|
|||
\
|
||||
classname& operator=(const chartype *str) \
|
||||
{ \
|
||||
free(m_str); \
|
||||
_freeHeap_wxString(m_str); \
|
||||
m_str = str ? strdupfunc(str) : NULL; \
|
||||
return *this; \
|
||||
} \
|
||||
\
|
||||
classname& operator=(const classname& src) \
|
||||
{ \
|
||||
free(m_str); \
|
||||
_freeHeap_wxString(m_str); \
|
||||
m_str = src.release(); \
|
||||
\
|
||||
return *this; \
|
||||
|
@ -93,7 +92,7 @@ public: \
|
|||
bool extend(size_t len) \
|
||||
{ \
|
||||
chartype * \
|
||||
str = (chartype *)realloc(m_str, (len + 1)*sizeof(chartype)); \
|
||||
str = (chartype *)_reallocHeap_wxString(m_str, (len + 1)*sizeof(chartype)); \
|
||||
if ( !str ) \
|
||||
return false; \
|
||||
\
|
||||
|
@ -124,14 +123,14 @@ public: \
|
|||
}
|
||||
#endif // wxABI_VERSION >= 20804
|
||||
|
||||
DEFINE_BUFFER(wxCharBuffer, char, wxStrdupA);
|
||||
DEFINE_BUFFER(wxCharBuffer, char, _mswHeap_Strdup);
|
||||
#if wxABI_VERSION >= 20804
|
||||
DEFINE_WRITABLE_BUFFER(wxWritableCharBuffer, wxCharBuffer, char);
|
||||
#endif
|
||||
|
||||
#if wxUSE_WCHAR_T
|
||||
|
||||
DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxStrdupW);
|
||||
DEFINE_BUFFER(wxWCharBuffer, wchar_t, _mswHeap_Strdup);
|
||||
#if wxABI_VERSION >= 20804
|
||||
DEFINE_WRITABLE_BUFFER(wxWritableWCharBuffer, wxWCharBuffer, wchar_t);
|
||||
#endif
|
||||
|
@ -173,10 +172,10 @@ public:
|
|||
// everyting is private as it can only be used by wxMemoryBuffer
|
||||
private:
|
||||
wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
|
||||
: m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
|
||||
: m_data(size ? _allocHeap_wxObject(size) : NULL), m_size(size), m_len(0), m_ref(0)
|
||||
{
|
||||
}
|
||||
~wxMemoryBufferData() { free(m_data); }
|
||||
~wxMemoryBufferData() { _freeHeap_wxObject(m_data); }
|
||||
|
||||
|
||||
void ResizeIfNeeded(size_t newSize)
|
||||
|
@ -184,10 +183,10 @@ private:
|
|||
if (newSize > m_size)
|
||||
{
|
||||
void *dataOld = m_data;
|
||||
m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
|
||||
m_data = _reallocHeap_wxObject(m_data, newSize + wxMemoryBufferData::DefBufSize);
|
||||
if ( !m_data )
|
||||
{
|
||||
free(dataOld);
|
||||
_freeHeap_wxObject(dataOld);
|
||||
}
|
||||
|
||||
m_size = newSize + wxMemoryBufferData::DefBufSize;
|
||||
|
|
|
@ -113,7 +113,7 @@ private:
|
|||
_WX_DECLARE_BASEARRAY_2(T, name, name##_Predicate, classexp)
|
||||
|
||||
#define _WX_DECLARE_BASEARRAY_2(T, name, predicate, classexp) \
|
||||
classexp name : public std::vector<T> \
|
||||
classexp name : public std::vector< T,wxStringAllocator< T > > \
|
||||
{ \
|
||||
typedef predicate Predicate; \
|
||||
typedef predicate::CMPFUNC SCMPFUNC; \
|
||||
|
|
|
@ -174,10 +174,10 @@ private:
|
|||
}; \
|
||||
\
|
||||
VC6_WORKAROUND(elT, liT, decl) \
|
||||
decl liT : public std::list<elT> \
|
||||
decl liT : public std::list< elT, wxObjectAllocator< elT > > \
|
||||
{ \
|
||||
private: \
|
||||
typedef std::list<elT> BaseListType; \
|
||||
typedef std::list< elT, wxObjectAllocator< elT > > BaseListType; \
|
||||
static BaseListType EmptyList; \
|
||||
\
|
||||
bool m_destroy; \
|
||||
|
@ -187,7 +187,7 @@ private:
|
|||
{ \
|
||||
private: \
|
||||
/* Workaround for broken VC6 nested class name resolution */ \
|
||||
typedef std::list<elT>::iterator iterator; \
|
||||
typedef std::list<elT, wxObjectAllocator< elT > >::iterator iterator; \
|
||||
friend class liT; \
|
||||
\
|
||||
iterator m_iter; \
|
||||
|
|
|
@ -1,30 +1,53 @@
|
|||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
extern void _allocateHeap_wxString();
|
||||
extern void _createHeap_wxString();
|
||||
extern void _destroyHeap_wxString();
|
||||
extern void* _allocHeap_wxString( size_t size );
|
||||
extern void* _reallocHeap_wxString( void* original, size_t size );
|
||||
extern void _freeHeap_wxString( void* ptr );
|
||||
extern char* _mswHeap_Strdup( const char* src );
|
||||
extern wchar_t* _mswHeap_Strdup( const wchar_t* src );
|
||||
|
||||
extern void _allocateHeap_wxObject();
|
||||
|
||||
extern void _createHeap_wxObject();
|
||||
extern void _destroyHeap_wxObject();
|
||||
extern void* _allocHeap_wxObject( size_t size );
|
||||
extern void* _reallocHeap_wxObject( void* original, size_t size );
|
||||
extern void _freeHeap_wxObject( void* ptr );
|
||||
|
||||
// _pxDestroy_ uses microsoft's internal definition for _Destroy(), found in xmemory;
|
||||
// which suppresses a warning that we otherwise get. The warning appears to be specific
|
||||
// to MSVC, so a basic _MSC_VER define will hopefully do the trick to allow support to
|
||||
// non-Micrsoft compilers.
|
||||
template<class T> inline
|
||||
void _pxDestroy_(T* _Ptr)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
_Destroy( _Ptr );
|
||||
#else
|
||||
(_Ptr)->~T();
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// wxStringAllocator
|
||||
// --------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
class wxStringAllocator
|
||||
{
|
||||
public :
|
||||
// typedefs
|
||||
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
public :
|
||||
// convert an allocator<T> to allocator<U>
|
||||
|
@ -37,7 +60,7 @@ public :
|
|||
public :
|
||||
wxStringAllocator()
|
||||
{
|
||||
_allocateHeap_wxString();
|
||||
_createHeap_wxString();
|
||||
}
|
||||
|
||||
~wxStringAllocator()
|
||||
|
@ -79,15 +102,14 @@ public :
|
|||
// standard placement-new syntax to initialize the object:
|
||||
void construct(pointer p, const T& t) { new(p) T(t); }
|
||||
// standard placement destructor:
|
||||
void destroy(pointer p) { p->~T(); }
|
||||
void destroy(pointer p) { _pxDestroy_(p); }
|
||||
|
||||
bool operator==(wxStringAllocator const&) { return true; }
|
||||
bool operator!=(wxStringAllocator const& a) { return !operator==(a); }
|
||||
}; // end of class Allocator
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
//
|
||||
// wxObjectAllocator
|
||||
// --------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
class wxObjectAllocator
|
||||
|
@ -95,13 +117,13 @@ class wxObjectAllocator
|
|||
public :
|
||||
// typedefs
|
||||
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
public :
|
||||
// convert an allocator<T> to allocator<U>
|
||||
|
@ -114,7 +136,7 @@ public :
|
|||
public :
|
||||
wxObjectAllocator()
|
||||
{
|
||||
_allocateHeap_wxObject();
|
||||
_createHeap_wxObject();
|
||||
}
|
||||
|
||||
~wxObjectAllocator()
|
||||
|
@ -155,8 +177,9 @@ public :
|
|||
|
||||
// standard placement-new syntax to initialize the object:
|
||||
void construct(pointer p, const T& t) { new(p) T(t); }
|
||||
|
||||
// standard placement destructor:
|
||||
void destroy(pointer p) { p->~T(); }
|
||||
void destroy(pointer p) { _pxDestroy_(p); }
|
||||
|
||||
bool operator==(wxObjectAllocator const&) { return true; }
|
||||
bool operator!=(wxObjectAllocator const& a) { return !operator==(a); }
|
||||
|
|
|
@ -436,13 +436,13 @@ public:
|
|||
#if wxUSE_PRIVATE_HEAP && defined(__WXMSW__)
|
||||
void* operator new( size_t size, const wxChar * = NULL, int = 0 )
|
||||
{
|
||||
_allocateHeap_wxObject();
|
||||
_createHeap_wxObject();
|
||||
return _allocHeap_wxObject( size );
|
||||
}
|
||||
|
||||
void *operator new[] ( size_t size, const wxChar * = NULL, int = 0 )
|
||||
{
|
||||
_allocateHeap_wxObject();
|
||||
_createHeap_wxObject();
|
||||
return _allocHeap_wxObject( size );
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,9 @@ wxStringInputStream::~wxStringInputStream()
|
|||
{
|
||||
#if wxUSE_UNICODE
|
||||
// Note: wx[W]CharBuffer uses malloc()/free()
|
||||
free(m_buf);
|
||||
// PCSX2 : wx[W]CharBuffer now uses the wxString local heap! --air
|
||||
//free(m_buf);
|
||||
_freeHeap_wxString(m_buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,11 @@ bool wxTextFile::OnRead(const wxMBConv& conv)
|
|||
}
|
||||
#endif // wxUSE_UNICODE
|
||||
|
||||
free(buf.release()); // we don't need this memory any more
|
||||
// we don't need this memory any more
|
||||
// PCSX2 : So let's free it using the buffer object's API, instead of some idiotic
|
||||
// low-level hack (bug found thanks to the use of custom heap allocation). --air
|
||||
//free(buf.release());
|
||||
buf.reset();
|
||||
|
||||
|
||||
// now break the buffer in lines
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
// HeapAllocator.cpp
|
||||
//
|
||||
// Copyright 2009-2010 by the PCSX Dev Team.
|
||||
// (under whatever license is appropriate for this sort of hack, I guess).
|
||||
//
|
||||
// Provides a specialized heap for wxStrings, which helps keep the main heap from being
|
||||
// excessively fragmented/cluttered by billions of micro-sized string allocations. This
|
||||
// should also improve multithreaded performace since strings can be allocated in parallel
|
||||
// with other "common" allocation tasks on other threads.
|
||||
//
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
|
@ -26,7 +37,7 @@ static int win32_string_heap_refcount;
|
|||
static HANDLE win32_object_heap = INVALID_HANDLE_VALUE;
|
||||
static int win32_object_heap_refcount;
|
||||
|
||||
void _allocateHeap_wxString()
|
||||
void _createHeap_wxString()
|
||||
{
|
||||
if( win32_string_heap == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
|
@ -45,13 +56,45 @@ void* _allocHeap_wxString( size_t size )
|
|||
return (void*)HeapAlloc( win32_string_heap, 0, size );
|
||||
}
|
||||
|
||||
void* _reallocHeap_wxString( void* original, size_t size )
|
||||
{
|
||||
if( !original )
|
||||
return _allocHeap_wxString( size );
|
||||
else
|
||||
return (void*)HeapReAlloc( win32_string_heap, 0, original, size );
|
||||
}
|
||||
|
||||
void _freeHeap_wxString( void* ptr )
|
||||
{
|
||||
HeapFree( win32_string_heap, 0, ptr );
|
||||
}
|
||||
|
||||
|
||||
void _allocateHeap_wxObject()
|
||||
char* _mswHeap_Strdup( const char* src )
|
||||
{
|
||||
if( !src ) return NULL;
|
||||
const size_t len = strlen(src);
|
||||
char* retval = (char*)_allocHeap_wxString( len+1 );
|
||||
if( !retval ) return NULL;
|
||||
memcpy( retval, src, len+1 );
|
||||
return retval;
|
||||
}
|
||||
|
||||
wchar_t* _mswHeap_Strdup( const wchar_t* src )
|
||||
{
|
||||
if( !src ) return NULL;
|
||||
const size_t len = (wcslen(src) + 1) * sizeof(wchar_t);
|
||||
wchar_t* retval = (wchar_t*)_allocHeap_wxString( len );
|
||||
if( !retval ) return NULL;
|
||||
memcpy( retval, src, len );
|
||||
return retval;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
//
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
||||
void _createHeap_wxObject()
|
||||
{
|
||||
if( win32_object_heap == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
|
@ -70,6 +113,14 @@ void* _allocHeap_wxObject( size_t size )
|
|||
return (void*)HeapAlloc( win32_object_heap, 0, size );
|
||||
}
|
||||
|
||||
void* _reallocHeap_wxObject( void* original, size_t size )
|
||||
{
|
||||
if( !original )
|
||||
return _allocHeap_wxObject( size );
|
||||
else
|
||||
return (void*)HeapReAlloc( win32_object_heap, 0, original, size );
|
||||
}
|
||||
|
||||
void _freeHeap_wxObject( void* ptr )
|
||||
{
|
||||
HeapFree( win32_object_heap, 0, ptr );
|
||||
|
|
Loading…
Reference in New Issue