Polaris: HeapStats.cc Source File

HeapStats.cc

Go to the documentation of this file.
00001 ///
00002 /// \file HeapStats.cc
00003 //Modification History:
00004 ///  98-05-20 evansl@cs.tamu.edu(Larry Evans)
00005 ///    WHAT:
00006 ///      1.added operator new[] and operator delete[]
00007 ///      2.Removed all but call to HeapStats::_hs_delete from operator
00008 ///        delete(void*).
00009 ///    WHY:
00010 ///      1.to avoid misleading memory leak reports.
00011 ///      2.The changes made to Listable::operator delete(void*) and
00012 ///        dec_refs_delete_or_zombie make the removed code useless.
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 //HeapStats::_hs_record( void *new_obj, size_t sz )
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;/// ... to prevent recording following news
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;/// ... to restart recording news
00179     }
00180 
00181     return new_obj;
00182 }
00183 
00184     static
00185   void*
00186 //check_new(size_t sz)
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 //HeapStats::_hs_new(size_t sz)
00205 HeapStats::_hs_new(unsigned int sz)
00206 {
00207     void *new_obj = check_new(sz);
00208    return new_obj;
00209 ///  return _hs_record( new_obj, sz );
00210 }
00211 
00212 void
00213 HeapStats::_hs_remove(void *p)
00214 {
00215     if (p) {
00216         Listable* lp=(Listable*)p;
00217     /// ... cout<<"+HeapStats::_hs_remove:"<<p<<endl;
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     /// ... cout<<"-HeapStats::_hs_remove:"<<p<<endl;
00234     }
00235 }
00236 
00237 void
00238 HeapStats::_hs_delete(void *p)
00239 {
00240     if (p) {
00241 
00242 ///     _hs_remove( p );
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 //operator new(size_t sz)
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 //operator new[](size_t sz)
00282 operator new[](unsigned int sz)
00283 { 
00284 ; void* p=operator new(sz)
00285 //; cout<<"new[]:"<<p<<endl
00286 ; return p
00287 ;}
00288 #endif
00289 #define DELETE_VEC
00290 #ifdef DELETE_VEC
00291 void 
00292 operator delete[](void* p)
00293 { 
00294 //; cout<<"delete[]:"<<p<<endl 
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 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:54 2005