Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/express/memoryUsage.h

Go to the documentation of this file.
00001 // Filename: memoryUsage.h
00002 // Created by:  drose (25May00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #ifndef MEMORYUSAGE_H
00020 #define MEMORYUSAGE_H
00021 
00022 #include "pandabase.h"
00023 
00024 #ifdef DO_MEMORY_USAGE
00025 
00026 #include "typedObject.h"
00027 #include "memoryInfo.h"
00028 #include "memoryUsagePointerCounts.h"
00029 #include "pmap.h"
00030 #include "dallocator.h"
00031 
00032 class ReferenceCount;
00033 class MemoryUsagePointers;
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //       Class : MemoryUsage
00037 // Description : This class is used strictly for debugging purposes,
00038 //               specifically for tracking memory leaks of
00039 //               reference-counted objects: it keeps a record of every
00040 //               such object currently allocated.
00041 //
00042 //               When compiled with NDEBUG set, this entire class does
00043 //               nothing and compiles to nothing.
00044 ////////////////////////////////////////////////////////////////////
00045 class EXPCL_PANDAEXPRESS MemoryUsage {
00046 public:
00047   INLINE static bool get_track_memory_usage();
00048 
00049 #if defined(__GNUC__)
00050   // There seems to be a problem with egcs-2.91.66: it gets confused
00051   // with too many nested inline functions, and sets the wrong pointer
00052   // as 'this'.  Yucky.  The workaround is to make these functions
00053   // non-inline, but this is inner-loop stuff, and we'd rather not pay
00054   // the price universally.  So we only compile them non-inline when
00055   // we're building on GCC.
00056   static void record_pointer(ReferenceCount *ptr);
00057   static void update_type(ReferenceCount *ptr, TypeHandle type);
00058   static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
00059   static void remove_pointer(ReferenceCount *ptr);
00060 #else // __GNUC__
00061   INLINE static void record_pointer(ReferenceCount *ptr);
00062   INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
00063   INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
00064   INLINE static void remove_pointer(ReferenceCount *ptr);
00065 #endif // __GNUC__
00066 
00067 public:
00068   static void *operator_new_handler(size_t size);
00069   static void operator_delete_handler(void *ptr);
00070 
00071 #if defined(WIN32_VC) && defined(_DEBUG)
00072   static int win32_malloc_hook(int alloc_type, void *ptr, 
00073                                size_t size, int block_use, long request, 
00074                                const unsigned char *filename, int line);
00075 #endif
00076     
00077 PUBLISHED:
00078   INLINE static bool is_tracking();
00079   INLINE static bool is_counting();
00080   INLINE static size_t get_current_cpp_size();
00081   INLINE static bool has_cpp_size();
00082   INLINE static size_t get_cpp_size();
00083   INLINE static bool has_interpreter_size();
00084   INLINE static size_t get_interpreter_size();
00085   INLINE static bool has_total_size();
00086   INLINE static size_t get_total_size();
00087 
00088   INLINE static int get_num_pointers();
00089   INLINE static void get_pointers(MemoryUsagePointers &result);
00090   INLINE static void get_pointers_of_type(MemoryUsagePointers &result,
00091                                           TypeHandle type);
00092   INLINE static void get_pointers_of_age(MemoryUsagePointers &result,
00093                                          double from, double to);
00094   INLINE static void get_pointers_with_zero_count(MemoryUsagePointers &result);
00095 
00096   INLINE static void freeze();
00097 
00098   INLINE static void show_current_types();
00099   INLINE static void show_trend_types();
00100   INLINE static void show_current_ages();
00101   INLINE static void show_trend_ages();
00102 
00103 private:
00104   MemoryUsage();
00105   static MemoryUsage *get_global_ptr();
00106 
00107   void ns_record_pointer(ReferenceCount *ptr);
00108   void ns_update_type(ReferenceCount *ptr, TypeHandle type);
00109   void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
00110   void ns_remove_pointer(ReferenceCount *ptr);
00111 
00112   void ns_record_void_pointer(void *ptr, size_t size);
00113   void ns_remove_void_pointer(void *ptr);
00114 
00115   size_t ns_get_current_cpp_size();
00116   size_t ns_get_cpp_size();
00117   size_t ns_get_interpreter_size();
00118   size_t ns_get_total_size();
00119   int ns_get_num_pointers();
00120   void ns_get_pointers(MemoryUsagePointers &result);
00121   void ns_get_pointers_of_type(MemoryUsagePointers &result,
00122                                TypeHandle type);
00123   void ns_get_pointers_of_age(MemoryUsagePointers &result,
00124                               double from, double to);
00125   void ns_get_pointers_with_zero_count(MemoryUsagePointers &result);
00126   void ns_freeze();
00127 
00128   void ns_show_current_types();
00129   void ns_show_trend_types();
00130   void ns_show_current_ages();
00131   void ns_show_trend_ages();
00132 
00133   void consolidate_void_ptr(MemoryInfo &info);
00134 
00135   static MemoryUsage *_global_ptr;
00136 
00137   // We shouldn't use a pmap, since that would be recursive!
00138   // Actually, it turns out that it doesn't matter, since somehow the
00139   // pallocator gets used even though we specify dallocator here, so
00140   // we have to make special code that handles the recursion anyway.
00141   typedef map<void *, MemoryInfo, less<void *>, dallocator<MemoryInfo> > Table;
00142   Table _table;
00143   int _freeze_index;
00144   int _count;
00145   size_t _current_cpp_size;
00146   size_t _cpp_size;
00147   size_t _interpreter_size;
00148   size_t _total_size;
00149 
00150   class TypeHistogram {
00151   public:
00152     void add_info(TypeHandle type, MemoryInfo &info);
00153     void show() const;
00154     void clear();
00155 
00156   private:
00157     // Cannot use a pmap, since that would be recursive!
00158     typedef map<TypeHandle, MemoryUsagePointerCounts, 
00159       less<TypeHandle>, dallocator<MemoryUsagePointerCounts> > Counts;
00160     Counts _counts;
00161   };
00162   TypeHistogram _trend_types;
00163 
00164   class AgeHistogram {
00165   public:
00166     AgeHistogram();
00167     void add_info(double age, MemoryInfo &info);
00168     void show() const;
00169     void clear();
00170 
00171   private:
00172     int choose_bucket(double age) const;
00173 
00174     enum { num_buckets = 5 };
00175     MemoryUsagePointerCounts _counts[num_buckets];
00176     static double _cutoff[num_buckets];
00177   };
00178   AgeHistogram _trend_ages;
00179 
00180 
00181   bool _track_memory_usage;
00182   bool _count_memory_usage;
00183 };
00184 
00185 #include "memoryUsage.I"
00186 
00187 #endif  // DO_MEMORY_USAGE
00188 
00189 #endif
00190 

Generated on Fri May 2 00:38:24 2003 for Panda by doxygen1.3