00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "docviewprec.h"
00012
00013 #ifdef __BORLANDC__
00014 #pragma hdrstop
00015 #endif
00016
00017 #ifndef WX_PRECOMP
00018 #include "wx/wx.h"
00019 #endif
00020
00021 #include "wx/general/a2dmemmgr.h"
00022
00023 #ifdef new
00024 #undef new
00025 #endif
00026
00027 a2dMemManager::~a2dMemManager()
00028 {
00029 for(a2dFreeList* fl = m_allLists; fl != NULL; )
00030 {
00031 wxASSERT(m_count>0);
00032 for(void* space = fl->m_topOfList; space != NULL; )
00033 {
00034 wxASSERT(fl->m_count>0);
00035 void* itemForDestroy = space;
00036 space = *((void**)space);
00037 delete itemForDestroy;
00038 fl->m_count --;
00039 }
00040 a2dFreeList* forDestroy = fl;
00041 fl = fl->m_next;
00042 delete forDestroy;
00043 m_count--;
00044 }
00045 }
00046
00047 void* a2dMemManager::Allocate(size_t bytes)
00048 {
00049
00050 for(a2dFreeList* fl = m_allLists;
00051 fl != NULL;
00052 fl = fl->m_next)
00053 {
00054 if(fl->m_blockSize == bytes)
00055 {
00056 if(fl->m_topOfList != NULL)
00057 {
00058 void* space = fl->m_topOfList;
00059 fl->m_topOfList = *((void**)(fl->m_topOfList));
00060 fl->m_count--;
00061 wxASSERT((fl->m_topOfList == NULL && fl->m_count == 0) || (fl->m_topOfList != NULL && fl->m_count !=0));
00062 return space;
00063 }
00064 break;
00065 }
00066 }
00067 void * newpointer = ::operator new(bytes);
00068 return newpointer;
00069 }
00070
00071 void a2dMemManager::Deallocate(void* space, size_t bytes)
00072 {
00073
00074
00075 a2dFreeList* fl;
00076 for(fl = m_allLists; fl != NULL; fl = fl->m_next)
00077 {
00078 if(fl->m_blockSize == bytes)
00079 break;
00080 }
00081 if(fl == NULL)
00082 {
00083 fl = new a2dFreeList(m_allLists, bytes);
00084 m_allLists = fl;
00085 m_count++;
00086 }
00087
00088 *((void**)space) = fl->m_topOfList;
00089 fl->m_topOfList = space;
00090 fl->m_count++;
00091 }
00092
00093 #ifdef __WXDEBUG__
00094 #if wxUSE_STACKWALKER
00095 #include "wx/stackwalk.h"
00096
00097 wxString a2dGetStackTrace(size_t skip, bool withArgs, int maxCalls, int maxLines)
00098 {
00099 wxString stackTrace;
00100
00101 class StackDump : public wxStackWalker
00102 {
00103 public:
00104 StackDump(int maxCalls = 20, bool withArgs = false) { m_curCall = 0; m_maxCalls = maxCalls; m_withArgs = withArgs; }
00105
00106 const wxString& GetStackTrace() const { return m_stackTrace; }
00107
00108 protected:
00109 virtual void OnStackFrame(const wxStackFrame& frame)
00110 {
00111 if(m_curCall>=m_maxCalls)
00112 return;
00113 m_curCall++;
00114 m_stackTrace << wxString::Format(_T("\t[%02d] "), frame.GetLevel());
00115
00116 wxString name = frame.GetName();
00117 if ( !name.empty() )
00118 {
00119 m_stackTrace << wxString::Format(_T("%-40s"), name.c_str());
00120 }
00121 else
00122 {
00123 m_stackTrace << wxString::Format
00124 (
00125 _T("0x%08lx"),
00126 (unsigned long)frame.GetAddress()
00127 );
00128 }
00129
00130 if(m_withArgs)
00131 {
00132 wxString type, val;
00133 size_t n;
00134 for ( n = 0; frame.GetParam(n, &type, &name, &val); n++ )
00135 {
00136 if(!n)
00137 m_stackTrace << wxT("\t(");
00138 else
00139 m_stackTrace << wxT(", ");
00140 m_stackTrace << wxString::Format(wxT("%s %s=%s"), type.c_str(), name.c_str(), val.Find(wxT('\n')) == wxNOT_FOUND ? val.c_str() : wxT("..."));
00141 }
00142 if(n)
00143 m_stackTrace << wxT(" )");
00144 }
00145
00146 if ( frame.HasSourceLocation() )
00147 {
00148 m_stackTrace << _T('\t')
00149 << frame.GetFileName()
00150 << _T(':')
00151 << frame.GetLine();
00152 }
00153
00154 m_stackTrace << _T('\n');
00155 }
00156
00157 private:
00158 wxString m_stackTrace;
00159 bool m_withArgs;
00160 int m_maxCalls;
00161 int m_curCall;
00162 };
00163
00164 StackDump dump(maxCalls,withArgs);
00165 dump.Walk(skip);
00166 stackTrace = dump.GetStackTrace();
00167
00168
00169
00170
00171 const int count = stackTrace.Freq(wxT('\n'));
00172 for ( int i = 0; i < count - maxLines; i++ )
00173 stackTrace = stackTrace.BeforeLast(wxT('\n'));
00174
00175 return stackTrace;
00176 }
00177 #endif // wxUSE_STACKWALKER
00178 #endif // __WXDEBUG__