memoryUsage.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Filename: memoryUsage.h
  2. // Created by: drose (25May00)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://etc.cmu.edu/panda3d/docs/license/ .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #ifndef MEMORYUSAGE_H
  19. #define MEMORYUSAGE_H
  20. #include "pandabase.h"
  21. #ifdef DO_MEMORY_USAGE
  22. #include "typedObject.h"
  23. #include "memoryInfo.h"
  24. #include "memoryUsagePointerCounts.h"
  25. #include "pmap.h"
  26. #include "dallocator.h"
  27. class ReferenceCount;
  28. class MemoryUsagePointers;
  29. ////////////////////////////////////////////////////////////////////
  30. // Class : MemoryUsage
  31. // Description : This class is used strictly for debugging purposes,
  32. // specifically for tracking memory leaks of
  33. // reference-counted objects: it keeps a record of every
  34. // such object currently allocated.
  35. //
  36. // When compiled with NDEBUG set, this entire class does
  37. // nothing and compiles to nothing.
  38. ////////////////////////////////////////////////////////////////////
  39. class EXPCL_PANDAEXPRESS MemoryUsage {
  40. public:
  41. INLINE static bool get_track_memory_usage();
  42. #if defined(__GNUC__)
  43. // There seems to be a problem with egcs-2.91.66: it gets confused
  44. // with too many nested inline functions, and sets the wrong pointer
  45. // as 'this'. Yucky. The workaround is to make these functions
  46. // non-inline, but this is inner-loop stuff, and we'd rather not pay
  47. // the price universally. So we only compile them non-inline when
  48. // we're building on GCC.
  49. static void record_pointer(ReferenceCount *ptr);
  50. static void update_type(ReferenceCount *ptr, TypeHandle type);
  51. static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
  52. static void remove_pointer(ReferenceCount *ptr);
  53. #else // __GNUC__
  54. INLINE static void record_pointer(ReferenceCount *ptr);
  55. INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
  56. INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
  57. INLINE static void remove_pointer(ReferenceCount *ptr);
  58. #endif // __GNUC__
  59. public:
  60. static void *operator_new_handler(size_t size);
  61. static void operator_delete_handler(void *ptr);
  62. #if defined(WIN32_VC) && defined(_DEBUG)
  63. static int win32_malloc_hook(int alloc_type, void *ptr,
  64. size_t size, int block_use, long request,
  65. const unsigned char *filename, int line);
  66. #endif
  67. PUBLISHED:
  68. INLINE static bool is_tracking();
  69. INLINE static bool is_counting();
  70. INLINE static size_t get_current_cpp_size();
  71. INLINE static bool has_cpp_size();
  72. INLINE static size_t get_cpp_size();
  73. INLINE static bool has_interpreter_size();
  74. INLINE static size_t get_interpreter_size();
  75. INLINE static bool has_total_size();
  76. INLINE static size_t get_total_size();
  77. INLINE static int get_num_pointers();
  78. INLINE static void get_pointers(MemoryUsagePointers &result);
  79. INLINE static void get_pointers_of_type(MemoryUsagePointers &result,
  80. TypeHandle type);
  81. INLINE static void get_pointers_of_age(MemoryUsagePointers &result,
  82. double from, double to);
  83. INLINE static void get_pointers_with_zero_count(MemoryUsagePointers &result);
  84. INLINE static void freeze();
  85. INLINE static void show_current_types();
  86. INLINE static void show_trend_types();
  87. INLINE static void show_current_ages();
  88. INLINE static void show_trend_ages();
  89. private:
  90. MemoryUsage();
  91. static MemoryUsage *get_global_ptr();
  92. void ns_record_pointer(ReferenceCount *ptr);
  93. void ns_update_type(ReferenceCount *ptr, TypeHandle type);
  94. void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
  95. void ns_remove_pointer(ReferenceCount *ptr);
  96. void ns_record_void_pointer(void *ptr, size_t size);
  97. void ns_remove_void_pointer(void *ptr);
  98. size_t ns_get_current_cpp_size();
  99. size_t ns_get_cpp_size();
  100. size_t ns_get_interpreter_size();
  101. size_t ns_get_total_size();
  102. int ns_get_num_pointers();
  103. void ns_get_pointers(MemoryUsagePointers &result);
  104. void ns_get_pointers_of_type(MemoryUsagePointers &result,
  105. TypeHandle type);
  106. void ns_get_pointers_of_age(MemoryUsagePointers &result,
  107. double from, double to);
  108. void ns_get_pointers_with_zero_count(MemoryUsagePointers &result);
  109. void ns_freeze();
  110. void ns_show_current_types();
  111. void ns_show_trend_types();
  112. void ns_show_current_ages();
  113. void ns_show_trend_ages();
  114. void consolidate_void_ptr(MemoryInfo &info);
  115. static MemoryUsage *_global_ptr;
  116. // We shouldn't use a pmap, since that would be recursive!
  117. // Actually, it turns out that it doesn't matter, since somehow the
  118. // pallocator gets used even though we specify dallocator here, so
  119. // we have to make special code that handles the recursion anyway.
  120. typedef map<void *, MemoryInfo, less<void *>, dallocator<MemoryInfo> > Table;
  121. Table _table;
  122. int _freeze_index;
  123. int _count;
  124. size_t _current_cpp_size;
  125. size_t _cpp_size;
  126. size_t _interpreter_size;
  127. size_t _total_size;
  128. class TypeHistogram {
  129. public:
  130. void add_info(TypeHandle type, MemoryInfo &info);
  131. void show() const;
  132. void clear();
  133. private:
  134. // Cannot use a pmap, since that would be recursive!
  135. typedef map<TypeHandle, MemoryUsagePointerCounts,
  136. less<TypeHandle>, dallocator<MemoryUsagePointerCounts> > Counts;
  137. Counts _counts;
  138. };
  139. TypeHistogram _trend_types;
  140. class AgeHistogram {
  141. public:
  142. AgeHistogram();
  143. void add_info(double age, MemoryInfo &info);
  144. void show() const;
  145. void clear();
  146. private:
  147. int choose_bucket(double age) const;
  148. enum { num_buckets = 5 };
  149. MemoryUsagePointerCounts _counts[num_buckets];
  150. static double _cutoff[num_buckets];
  151. };
  152. AgeHistogram _trend_ages;
  153. bool _track_memory_usage;
  154. bool _count_memory_usage;
  155. };
  156. #include "memoryUsage.I"
  157. #endif // DO_MEMORY_USAGE
  158. #endif