Changeset c02f761
- Timestamp:
- May 4, 2018, 5:23:30 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
- Children:
- 43c461d
- Parents:
- 67db067
- Location:
- src/Common
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/Heap.cc
r67db067 rc02f761 7 7 // Heap.cc -- 8 8 // 9 // Author : Peter A. Buhr10 // Created On : 9 // Author : Thierry Delisle 10 // Created On : Thu May 3 16:16:10 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 3 16:16:10201813 // Update Count : 2 12 // Last Modified On : Fri May 4 17:17:59 2018 13 // Update Count : 27 14 14 // 15 15 … … 21 21 #include <iostream> 22 22 23 //#define WITH_HEAP_STATISTICS 24 23 25 namespace HeapStats { 24 25 26 #if !defined( WITH_HEAP_STATISTICS ) 27 void newPass( const char * const ) {} 26 28 27 28 29 30 31 32 33 29 void printStats() {} 30 #else 31 struct StatBlock { 32 const char * name = nullptr; 33 size_t mallocs = 0; 34 size_t frees = 0; 35 }; 34 36 35 StatBlock passes[100];36 37 size_t passes_cnt = 0;37 StatBlock passes[100] = {{ "Pre-Parse", 0, 0 }}; 38 const size_t passes_size = sizeof(passes) / sizeof(passes[0]); 39 size_t passes_cnt = 1; 38 40 39 40 41 42 43 41 void newPass( const char * const name ) { 42 passes[passes_cnt].name = name; 43 passes[passes_cnt].mallocs = 0; 44 passes[passes_cnt].frees = 0; 45 passes_cnt++; 44 46 45 assertf(passes_cnt < passes_size, "Too many passes for HeapStats, increase the size of the array in Heap.h"); 47 assertf(passes_cnt < passes_size, "Too many passes for HeapStats, increase the size of the array in Heap.h"); 48 } 49 50 void print(size_t value, size_t total) { 51 std::cerr << std::setw(12) << value; 52 std::cerr << "(" << std::setw(3); 53 std::cerr << (value == 0 ? 0 : value * 100 / total); 54 std::cerr << "%) | "; 55 } 56 57 void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees) { 58 std::cerr << std::setw(nc) << stat.name; 59 std::cerr << " | "; 60 61 print(stat.mallocs, total_mallocs); 62 print(stat.frees , total_frees ); 63 std::cerr << "\n"; 64 } 65 66 void print(char c, size_t nc) { 67 for(size_t i = 0; i < nc; i++) { 68 std::cerr << c; 69 } 70 std::cerr << '\n'; 71 } 72 73 void printStats() { 74 size_t nc = 0; 75 size_t total_mallocs = 0; 76 size_t total_frees = 0; 77 for(size_t i = 0; i < passes_cnt; i++) { 78 nc = std::max(nc, std::strlen(passes[i].name)); 79 total_mallocs += passes[i].mallocs; 80 total_frees += passes[i].frees; 81 } 82 size_t nct = nc + 44; 83 84 const char * const title = "Heap Usage Statistic"; 85 print('=', nct); 86 for(size_t i = 0; i < (nct - std::strlen(title)) / 2; i++) std::cerr << ' '; 87 std::cerr << title << std::endl; 88 print('-', nct); 89 std::cerr << std::setw(nc) << "Pass"; 90 std::cerr << " | Malloc Count | Free Count |" << std::endl; 91 92 print('-', nct); 93 for(size_t i = 0; i < passes_cnt; i++) { 94 print(passes[i], nc, total_mallocs, total_frees); 95 } 96 print('-', nct); 97 print({"Sum", total_mallocs, total_frees}, nc, total_mallocs, total_frees); 98 99 } 100 101 #include <stdarg.h> 102 #include <stddef.h> 103 #include <stdio.h> 104 #include <string.h> 105 #include <unistd.h> 106 #include <signal.h> 107 extern "C" { 108 #include <dlfcn.h> 109 #include <execinfo.h> 110 } 111 112 //============================================================================================= 113 // Interposing helpers 114 //============================================================================================= 115 116 typedef void (* generic_fptr_t)(void); 117 generic_fptr_t interpose_symbol( const char * symbol, const char * version ) { 118 const char * error; 119 120 static void * library; 121 if ( ! library ) { 122 #if defined( RTLD_NEXT ) 123 library = RTLD_NEXT; 124 #else 125 // missing RTLD_NEXT => must hard-code library name, assuming libstdc++ 126 library = dlopen( "libc.so.6", RTLD_LAZY ); 127 error = dlerror(); 128 if ( error ) { 129 std::cerr << "interpose_symbol : failed to open libc, " << error << std::endl; 130 abort(); 131 } 132 #endif 133 } // if 134 135 generic_fptr_t fptr; 136 137 #if defined( _GNU_SOURCE ) 138 if ( version ) { 139 fptr = (generic_fptr_t)dlvsym( library, symbol, version ); 140 } else { 141 fptr = (generic_fptr_t)dlsym( library, symbol ); 142 } 143 #else 144 fptr = (generic_fptr_t)dlsym( library, symbol ); 145 #endif // _GNU_SOURCE 146 147 error = dlerror(); 148 if ( error ) { 149 std::cerr << "interpose_symbol : internal error, " << error << std::endl; 150 abort(); 46 151 } 47 152 48 void print(size_t value, size_t total) { 49 std::cerr << std::setw(12) << value; 50 std::cerr << "(" << std::setw(3); 51 std::cerr << (value == 0 ? 0 : value * 100 / total); 52 std::cerr << "%) | "; 153 return fptr; 154 } 155 156 extern "C" { 157 void * malloc( size_t size ) __attribute__((malloc)); 158 void * malloc( size_t size ) { 159 static auto __malloc = reinterpret_cast<void * (*)(size_t)>(interpose_symbol( "malloc", nullptr )); 160 if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++; 161 return __malloc( size ); 53 162 } 54 163 55 void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees) { 56 std::cerr << std::setw(nc) << stat.name; 57 std::cerr << " | "; 58 59 print(stat.mallocs, total_mallocs); 60 print(stat.frees , total_frees ); 61 std::cerr << "\n"; 164 void free( void * ptr ) { 165 static auto __free = reinterpret_cast<void (*)(void *)>(interpose_symbol( "free", nullptr )); 166 if( passes_cnt > 0 ) passes[passes_cnt - 1].frees++; 167 return __free( ptr ); 62 168 } 63 169 64 void print(char c, size_t nc) { 65 for(size_t i = 0; i < nc; i++) { 66 std::cerr << c; 67 } 68 std::cerr << '\n'; 170 void * calloc( size_t nelem, size_t size ) { 171 static auto __calloc = reinterpret_cast<void * (*)(size_t, size_t)>(interpose_symbol( "calloc", nullptr )); 172 if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++; 173 return __calloc( nelem, size ); 69 174 } 70 175 71 void printStats() { 72 size_t nc = 0; 73 size_t total_mallocs = 0; 74 size_t total_frees = 0; 75 for(size_t i = 0; i < passes_cnt; i++) { 76 nc = std::max(nc, std::strlen(passes[i].name)); 77 total_mallocs += passes[i].mallocs; 78 total_frees += passes[i].frees; 79 } 80 size_t nct = nc + 44; 81 82 const char * const title = "Heap Usage Statistic"; 83 print('=', nct); 84 for(size_t i = 0; i < (nct - std::strlen(title)) / 2; i++) std::cerr << ' '; 85 std::cerr << title << std::endl; 86 print('-', nct); 87 std::cerr << std::setw(nc) << "Pass"; 88 std::cerr << " | Malloc Count | Free Count |" << std::endl; 89 90 print('-', nct); 91 for(size_t i = 0; i < passes_cnt; i++) { 92 print(passes[i], nc, total_mallocs, total_frees); 93 } 94 print('-', nct); 95 print({"Sum", total_mallocs, total_frees}, nc, total_mallocs, total_frees); 96 176 void * realloc( void * ptr, size_t size ) { 177 static auto __realloc = reinterpret_cast<void * (*)(void *, size_t)>(interpose_symbol( "realloc", nullptr )); 178 void * s = __realloc( ptr, size ); 179 if ( s != ptr && passes_cnt > 0 ) { // did realloc get new storage ? 180 passes[passes_cnt - 1].mallocs++; 181 passes[passes_cnt - 1].frees++; 182 } // if 183 return s; 97 184 } 98 #endif 185 } 186 #endif 99 187 } 100 -
src/Common/Heap.h
r67db067 rc02f761 7 7 // Heap.h -- 8 8 // 9 // Author : Peter A. Buhr10 // Created On : 9 // Author : Thierry Delisle 10 // Created On : Thu May 3 16:16:10 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 3 16:16:10201813 // Update Count : 212 // Last Modified On : Fri May 4 14:34:08 2018 13 // Update Count : 3 14 14 // 15 15
Note: See TracChangeset
for help on using the changeset viewer.