20 #include "../../include/lock.hpp"
48 MemoryTracker(
const MemoryTracker&);
49 MemoryTracker& operator=(
const MemoryTracker&);
59 alloc_node() : left_(0), right_(0) {}
75 size_tracker sizes[] =
93 const size_t size_elements(
sizeof(sizes) /
sizeof(size_tracker));
98 typedef Mutex::Lock Lock;
102 MemoryTracker theTracker;
105 bool lookup(alloc_node*& find,
void* key, alloc_node*& prev)
125 void insert(alloc_node*
entry)
132 alloc_node* tmp = Root;
133 alloc_node* prev = 0;
135 if (
lookup(tmp, entry, prev))
141 prev->right_ =
entry;
145 alloc_node* predecessorSwap(alloc_node* del)
147 alloc_node* pred = del->left_;
148 alloc_node* predPrev = del;
150 while (pred->right_) {
155 predPrev->left_ = pred->left_;
157 predPrev->right_ = pred->left_;
159 pred->left_ = del->left_;
160 pred->right_ = del->right_;
167 void remove(
void* ptr)
169 alloc_node* del = Root;
170 alloc_node* prev = 0;
173 if (
lookup(del, ptr, prev) ==
false)
176 if (del->left_ && del->right_)
177 replace = predecessorSwap(del);
178 else if (!del->left_ && !del->right_)
181 replace = (del->left_) ? del->left_ : del->right_;
185 else if (prev->left_ == del)
186 prev->left_ = replace;
188 prev->right_ = replace;
192 typedef void (*fp)(alloc_node*,
void*);
194 void applyInOrder(alloc_node* root, fp f,
void* arg)
199 applyInOrder(root->left_, f, arg);
201 applyInOrder(root->right_, f, arg);
205 void show(alloc_node* ptr,
void* arg)
207 std::ofstream* log =
static_cast<std::ofstream*
>(arg);
212 MemoryTracker::MemoryTracker() : log_(
"memory.log")
216 setenv(
"GLIBCPP_FORCE_NEW",
"1", 0);
224 log_ <<
"MSVC " << msvcFac <<
"workaround" << std::endl;
232 MemoryTracker::~MemoryTracker()
243 void MemoryTracker::LogStats()
245 log_ <<
"Number of Allocs: " << Allocs <<
'\n';
246 log_ <<
"Number of DeAllocs: " << DeAllocs <<
'\n';
247 log_ <<
"Number of bytes used: " << Bytes <<
'\n';
249 log_ <<
"Alloc size table:\n";
250 log_ <<
" Bytes " <<
'\t' <<
" Times\n";
252 for (
size_t i = 0;
i < size_elements; ++
i) {
253 log_ <<
" " << sizes[
i].size_ <<
" " <<
'\t';
254 log_ << std::setiosflags(std::ios::right) << std::setw(8);
255 log_ << sizes[
i].count_ <<
'\n';
258 if (Allocs != DeAllocs) {
259 log_<<
"Showing new'd allocs with no deletes" <<
'\n';
260 applyInOrder(Root, show, &log_);
267 size_t powerOf2(
size_t sz)
281 return shifts < size_elements ? shifts : size_elements;
288 void*
operator new(
size_t sz)
291 void* ptr = malloc(sz +
sizeof(alloc_node));
297 ++sizes[powerOf2(sz)].count_;
298 insert(
new (ptr) alloc_node);
300 return static_cast<char*
>(ptr) +
sizeof(alloc_node);
307 void operator delete(
void* ptr)
310 ptr =
static_cast<char*
>(ptr) -
sizeof(alloc_node);
321 void*
operator new[](
size_t sz)
323 return ::operator
new(sz);
327 void operator delete[](
void* ptr)
329 ::operator
delete(ptr);
335 void* XMALLOC(
size_t sz,
void* head)
337 return ::operator
new(sz);
340 void* XREALLOC(
void* ptr,
size_t sz,
void*
heap)
342 void*
ret = ::operator
new(sz);
345 memcpy(ret, ptr, sz);
348 ::operator
delete(ptr);
353 void XFREE(
void* ptr,
void* heap)
355 ::operator
delete(ptr);