source: src/Common/Heap.cc@ 682dcae

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum with_gc
Last change on this file since 682dcae was 10cfad9, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Fixed bad merge

  • Property mode set to 100644
File size: 5.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Heap.cc --
8//
9// Author : Thierry Delisle
10// Created On : Thu May 3 16:16:10 2018
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri May 4 17:27:31 2018
13// Update Count : 28
14//
15
16#include <cassert>
17#include <cmath>
18#include <cstddef>
19#include <cstring>
20#include <iomanip>
21#include <iostream>
22
23//#define WITH_HEAP_STATISTICS
24
25namespace HeapStats {
26#if !defined( WITH_HEAP_STATISTICS )
27 void newPass( const char * const ) {}
28
29 void printStats() {}
30#else
31 struct StatBlock {
32 const char * name = nullptr;
33 size_t mallocs = 0;
34 size_t frees = 0;
35 };
36
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;
40
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++;
46
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 // RTLD_NEXT
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();
151 }
152
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 );
162 }
163
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 );
168 }
169
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 );
174 }
175
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;
184 }
185 }
186#endif
187}
Note: See TracBrowser for help on using the repository browser.