📄 tmgdmalloc.c.fancy
字号:
#include "tmgdmalloc.h"#include <stdio.h>// -------------------------------------------------------------------------//// To debug the internals of TMG Dmalloc////struct __TMG_internal { const char* file; unsigned line;};extern hash_map<void*, __TMG_internal*> __tmg_internals;extern unsigned __tmg_internalallocs;extern void __tmg_internaldel(void *p);template<class C>inlineC*__tmg_internalnew(C *p, const char* file, unsigned line){ assert(__tmg_internals.find(p) == __tmg_internals.end()); __TMG_internal *tmgint = new __TMG_internal; tmgint->file = file; tmgint->line = line; __tmg_internals[p] = tmgint; return p;}void__tmg_internaldel(void *p){ assert(__tmg_internals.find(p) != __tmg_internals.end()); __TMG_internal *tmgint = __tmg_internals[p]; delete tmgint; __tmg_internals.erase(p);}// # define TMGNEW(X, args...) __tmg_internalnew<X>(new X(args), __FILE__, __LINE__);// # define TMGDEL(x) (__tmg_internaldel((void*)x), delete x)# define TMGNEW(X, args...) new X(args)# define TMGDEL(x) delete x//// -------------------------------------------------------------------------//struct __TMG_c2info;// maps typeid class name to a __TMG_filemaptypedef hash_map<unsigned, __TMG_c2info*> __TMG_sizemap;// maps a line number to a __TMG_sizemaptypedef hash_map<unsigned, unsigned> __TMG_linemap;// maps a file name to a __TMG_linemaptypedef hash_map<const char*, __TMG_linemap*> __TMG_filemap;struct __TMG_c2info { __TMG_c2info() { allocs = 0; files = TMGNEW(__TMG_filemap); assert(files); } ~__TMG_c2info() { assert(!allocs); assert(!files->size()); TMGDEL(files); } unsigned allocs; __TMG_filemap *files;};// maps pointers to all the info one would want about itstruct __TMG_p2info { __TMG_p2info(const char *f, unsigned l, size_t s) : file(f), line(l), size(s) {} const char *file; unsigned line; size_t size;};typedef hash_map<void*, __TMG_p2info*> __TMG_p2infomap;__TMG_sizemap __tmg_smap;__TMG_p2infomap __tmg_p2infomap;unsigned __tmg_totalallocs = 0;// to debug TMG Dmalloc itselfunsigned __tmg_internalallocs = 0;hash_map<void*, __TMG_internal*> __tmg_internals;void__tmg_dmalloc_new(void *p, size_t size, const char *fname, unsigned lineno){ __TMG_c2info *c2i = 0; __TMG_linemap *linemap = 0; // find the class entry and update the number of allocs if(__tmg_smap.find(size) == __tmg_smap.end()) { c2i = TMGNEW(__TMG_c2info); assert(c2i); __tmg_smap[size] = c2i; } else { c2i = __tmg_smap[size]; } c2i->allocs++; // in correct file/linenumber entry do update if(c2i->files->find(fname) == c2i->files->end()) { linemap = TMGNEW(__TMG_linemap); assert(linemap); (*c2i->files)[fname] = linemap; } else { linemap = (*c2i->files)[fname]; } (*linemap)[lineno]++; // now take care of the entry to map pointer to the info assert(__tmg_p2infomap.find(p) == __tmg_p2infomap.end()); __TMG_p2info *p2i = TMGNEW(__TMG_p2info, fname, lineno, size); assert(p2i); __tmg_p2infomap[p] = p2i; __tmg_totalallocs++;}void__tmg_dmalloc_del(void *p){ if(__tmg_p2infomap.find(p) == __tmg_p2infomap.end()) return; // find the information that maps the void pointer to all the // required information and delete it from the info map. __TMG_p2info *p2i = 0; p2i = __tmg_p2infomap[p]; __tmg_p2infomap.erase(p); assert(__tmg_smap.find(p2i->size) != __tmg_smap.end()); __TMG_c2info *c2i = __tmg_smap[p2i->size]; c2i->allocs--; assert(c2i->files->find(p2i->file) != c2i->files->end()); __TMG_linemap *linemap = (*c2i->files)[p2i->file]; assert(linemap->find(p2i->line) != linemap->end()); if(!(--(*linemap)[p2i->line])) { linemap->erase(p2i->line); } if(!linemap->size()) { c2i->files->erase(p2i->file); TMGDEL(linemap); } if(!c2i->allocs) { assert(!c2i->files->size()); __tmg_smap.erase(p2i->size); TMGDEL(c2i); } TMGDEL(p2i); __tmg_totalallocs--;};void__tmg_dmalloc_info(void *p){ __TMG_p2info *p2i = 0; assert(__tmg_p2infomap.find(p) != __tmg_p2infomap.end()); p2i = __tmg_p2infomap[p]; printf("pointer %p, class size %d, file %s, line %d\n", p, p2i->size, p2i->file, p2i->line);}void__tmg_dmalloc_stats(){#ifndef WITH_TMGDMALLOC return;#else // for each class printf("TMG Dmalloc Stats\n------------------------------\n"); printf("Total allocs: %d\n", __tmg_totalallocs); for(__TMG_sizemap::const_iterator i = __tmg_smap.begin(); i != __tmg_smap.end(); ++i) { printf("size %d, allocated: %d\n", i->first, i->second->allocs); for(__TMG_filemap::const_iterator j = i->second->files->begin(); j != i->second->files->end(); j++) { for(__TMG_linemap::const_iterator k = j->second->begin(); k != j->second->end(); ++k) { printf(" %s:%d %d\n", j->first, k->first, k->second); } } } printf("\n"); // printf("TMG Dmalloc Internal Stats\n------------------------------\n"); // printf("Total allocs: %d\n", __tmg_internalallocs); // for(hash_map<void*, __TMG_internal*>::const_iterator i = __tmg_internals.begin(); i != __tmg_internals.end(); ++i) { // printf("pointer %p, %s:%d\n", i->first, i->second->file, i->second->line); // } // printf("\n");#endif}#ifdef WITH_TMGDMALLOCvoid *operator new(size_t size, const char* file, unsigned line) { void *p = malloc(size); __tmg_dmalloc_new(p, size, file, line); return p;}void *operator new[](size_t size, const char* file, unsigned line) { void *p = malloc(size); __tmg_dmalloc_new(p, size, file, line); return p;}/*voidoperator delete(void *p){ __tmg_dmalloc_del(p); free(p);}voidoperator delete[](void *p){ __tmg_dmalloc_del(p); free(p);}*/#else#include <list>using namespace std;#define CACHE_BLOB_MAX 512#define CACHE_MAX_PER_SIZE 65536struct __cache_sizeentry { // size_t size; __cache_sizeentry() { number = 0; pointers.clear(); } unsigned number; list<void*> pointers; // sklist_entry<__cache_sizeentry> _sortlink;};// skiplist<__cache_sizeentry, size_t, &__cache_sizeentry::size, &__cache_sizeentry::_sortlink> __cache;hash_map<void*, size_t> __cache_sizes;__cache_sizeentry __cache[CACHE_BLOB_MAX];inlinevoid *__cache_do_new(size_t size){ void *p = 0; // if you get fucked by this assert, increase CACHE_BLOB_MAX assert(size < CACHE_BLOB_MAX); if(!__cache[size].number) { p = malloc(size); } else { p = __cache[size].pointers.front(); __cache[size].pointers.pop_front(); __cache[size].number--; } __cache_sizes[p] = size; return p;}inlinevoid__cache_do_delete(void *p){ hash_map<void*, size_t>::iterator i = __cache_sizes.find(p); if(i == __cache_sizes.end()) return; if(__cache[i->second].number >= CACHE_MAX_PER_SIZE) free(p); else { __cache[i->second].number++; __cache[i->second].pointers.push_front(p); }}void *operator new(size_t size){ return malloc(size); // return __cache_do_new(size);}void *operator new[](size_t size){ return malloc(size); // return __cache_do_new(size);}#endifvoidoperator delete(void *p){ free(p); // __cache_do_delete(p);#ifdef WITH_TMGDMALLOC // __tmg_dmalloc_del(p);#endif}voidoperator delete[](void *p){ free(p); // __cache_do_delete(p);#ifdef WITH_TMGDMALLOC // __tmg_dmalloc_del(p);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -