HeapStats.ccGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifdef POLARIS_GNU_PRAGMAS
00015 #pragma implementation
00016 #endif
00017
00018
00019 #include <new>
00020
00021
00022
00023
00024 #include <iostream.h>
00025 #include <stdlib.h>
00026
00027 #include "Listable.h"
00028 #include "HeapStats.h"
00029 #include "Collection/Map.h"
00030
00031 #include "p-assert.h"
00032
00033 #include "GC_TRACE_MACS.h"
00034
00035 template class TypedBaseMap<HeapObject,HeapElem>;
00036 template class ProtoMap<HeapObject,HeapElem>;
00037 template class Map<HeapObject,HeapElem>;
00038 template ostream & operator << (ostream &, const Map<HeapObject,HeapElem> &);
00039 template class KeyIterator<HeapObject,HeapElem>;
00040
00041 int HeapStats::collect_news = 0;
00042 int HeapStats::collect_dels = 0;
00043 int HeapStats::num_news = 0;
00044 int HeapStats::num_deletes = 0;
00045
00046 Map<HeapObject,HeapElem> *HeapStats::objs = 0;
00047
00048 void
00049 HeapStats::stop()
00050 {
00051 collect_news = 0;
00052 collect_dels = 0;
00053 }
00054
00055 void
00056 HeapStats::stop_news()
00057 {
00058 collect_news = 0;
00059 }
00060
00061 void
00062 HeapStats::stop_dels()
00063 {
00064 collect_dels = 0;
00065 }
00066
00067 void
00068 HeapStats::restart()
00069 {
00070 collect_news = 1;
00071 collect_dels = 1;
00072 }
00073
00074 void
00075 HeapStats::start()
00076 {
00077 collect_news = 1;
00078 collect_dels = 1;
00079 }
00080
00081 void
00082 HeapStats::start_news()
00083 {
00084 collect_news = 1;
00085 }
00086
00087 void
00088 HeapStats::start_dels()
00089 {
00090 collect_dels = 1;
00091 }
00092
00093 void
00094 HeapStats::report(ostream & o)
00095 {
00096 o << num_news << " operator new calls\n";
00097 o << num_deletes << " operator delete calls\n";
00098 }
00099
00100 void
00101 HeapStats::reset(void)
00102 {
00103 if (objs != 0)
00104 delete objs;
00105
00106 objs = 0;
00107
00108 num_news = 0;
00109 num_deletes = 0;
00110 }
00111
00112 int
00113 HeapStats::memory_leak(void)
00114 {
00115 return (num_news != num_deletes);
00116 }
00117
00118 void
00119 HeapStats::print_memory_leaks(ostream & o)
00120 {
00121 if (objs == 0 || objs->entries() == 0)
00122 o << "There are no memory leaks\n";
00123 else {
00124 int num_leaks = objs->entries();
00125
00126 o << "There are " << num_leaks << " memory leaks:\n";
00127
00128 for (const HeapObject *p = objs->first_ref();
00129 p != 0; p = objs->successor_ref(*p)) {
00130 HeapElem *curr = objs->find_ref(*p);
00131
00132 o << " ptr = " << curr->ptr;
00133 o << ", size = " << curr->size;
00134
00135 #ifdef LISTABLE_DEBUG
00136 Listable & elem = *(Listable *) curr->ptr;
00137
00138 if (elem.fingerprint_ok())
00139 o << ", \"" << elem << "\"";
00140 #endif
00141
00142 o << "\n";
00143 }
00144 }
00145 }
00146
00147 void *
00148
00149 HeapStats::_hs_record( void *new_obj, unsigned int sz )
00150 {
00151 char *ptr = CASTAWAY(char *) new_obj;
00152
00153 #if POLARIS_DEBUG
00154 for (int count = sz; count > 0; --count)
00155 *ptr++ = 0x57;
00156 #endif
00157
00158 if (collect_news) {
00159
00160 num_news += 1;
00161
00162 collect_news = 0;
00163
00164 HeapElem *new_elem = new HeapElem;
00165
00166 new_elem->ptr = new_obj;
00167 new_elem->size = sz;
00168
00169 if (objs == 0)
00170 {
00171 objs = new Map<HeapObject,HeapElem>;
00172 }
00173
00174 HeapObject *addr = (HeapObject *) new_obj;
00175
00176 objs->ins( *addr, new_elem );
00177
00178 collect_news = 1;
00179 }
00180
00181 return new_obj;
00182 }
00183
00184 static
00185 void*
00186
00187 check_new(unsigned int sz)
00188 {
00189 #ifdef CLASS_INSTANCE_REGISTRY
00190 void *new_obj = pmalloc(sz);
00191 #else
00192 void *new_obj = malloc(sz);
00193 #endif
00194 #ifdef GC_TRACE_ALLOC_FREE
00195 cout<<"ALLOC:"<<new_obj<<endl;
00196 #endif
00197
00198 if (! new_obj)
00199 p_abort( "no more swap space" );
00200 return new_obj;
00201 }
00202
00203 void *
00204
00205 HeapStats::_hs_new(unsigned int sz)
00206 {
00207 void *new_obj = check_new(sz);
00208 return new_obj;
00209
00210 }
00211
00212 void
00213 HeapStats::_hs_remove(void *p)
00214 {
00215 if (p) {
00216 Listable* lp=(Listable*)p;
00217
00218 if (collect_dels) {
00219 num_deletes += 1;
00220
00221 collect_dels = 0;
00222
00223 if (objs != 0) {
00224 HeapObject *addr = (HeapObject *) p;
00225 HeapElem *curr = objs->find_ref(*addr);
00226
00227 if (curr != 0)
00228 objs->del(*addr);
00229 }
00230
00231 collect_dels = 1;
00232 }
00233
00234 }
00235 }
00236
00237 void
00238 HeapStats::_hs_delete(void *p)
00239 {
00240 if (p) {
00241
00242
00243 #ifdef GC_TRACE_ALLOC_FREE
00244 cout<<"FREE:"<<p<<endl;
00245 #endif
00246 #ifdef CLASS_INSTANCE_REGISTRY
00247 pfree(p);
00248 #else
00249 free(p);
00250 #endif
00251 }
00252 }
00253
00254
00255
00256 void *
00257
00258 operator new(unsigned int sz)throw (std::bad_alloc)
00259 {
00260
00261 void* p=HeapStats::_hs_new(sz);
00262 #ifdef GC_TRACE_NEWS
00263 cout<<"operator new:ptr="<<p<<" size="<<sz<<endl;
00264 #endif
00265 return p;
00266 }
00267
00268 void
00269 operator delete(void *p)throw ()
00270 {
00271 #ifdef GC_TRACE_DELETES
00272 cout<<"operator delete:"<<p<<endl;
00273 #endif
00274
00275 HeapStats::_hs_delete(p);
00276 }
00277
00278 #define NEW_VEC
00279 #ifdef NEW_VEC
00280 void *
00281
00282 operator new[](unsigned int sz)
00283 {
00284 ; void* p=operator new(sz)
00285
00286 ; return p
00287 ;}
00288 #endif
00289 #define DELETE_VEC
00290 #ifdef DELETE_VEC
00291 void
00292 operator delete[](void* p)
00293 {
00294
00295 ; operator delete(p)
00296 ;}
00297 #endif
00298
00299 Listable*
00300 HeapElem::listable_clone() const
00301 {
00302 return 0;
00303
00304 }
00305
00306 void
00307 HeapElem::print(ostream &o) const
00308 {
00309 o << " ptr = " << this->ptr;
00310 o << ", size = " << this->size;
00311
00312 Listable & listable = *(Listable *) this->ptr;
00313
00314 if (listable.fingerprint_ok())
00315 o << ", \"" << listable << "\"";
00316 }
00317
|