Browse Source

track python memory

David Rose 24 years ago
parent
commit
21c4a03c16

+ 38 - 0
panda/src/express/memoryUsage.I

@@ -161,7 +161,14 @@ get_current_cpp_size() {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool MemoryUsage::
 INLINE bool MemoryUsage::
 has_cpp_size() {
 has_cpp_size() {
+#if defined(WIN32_VC) && defined(_DEBUG)
+  // Windows in debug mode can count C++ size without having to do a
+  // full track.
+  return is_counting();
+#else
+  // Other systems require the full hammer.
   return is_tracking();
   return is_tracking();
+#endif
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -176,6 +183,37 @@ get_cpp_size() {
   return get_global_ptr()->ns_get_cpp_size();
   return get_global_ptr()->ns_get_cpp_size();
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: MemoryUsage::has_interpreter_size
+//       Access: Public, Static
+//  Description: Returns true if the value returned by
+//               get_interpreter_size() is meaningful on this particular
+//               system with this particular configuration, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool MemoryUsage::
+has_interpreter_size() {
+#ifdef TRACK_IN_INTERPRETER
+  return is_counting();
+#else
+  return false;
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: MemoryUsage::get_interpreter_size
+//       Access: Public, Static
+//  Description: Returns the total number of bytes of allocated memory
+//               while the high-level languange code is running.  This
+//               number is only meaningful if both Panda and the
+//               high-level language are single-threaded, and running
+//               in the same thread.
+////////////////////////////////////////////////////////////////////
+INLINE size_t MemoryUsage::
+get_interpreter_size() {
+  return get_global_ptr()->ns_get_interpreter_size();
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MemoryUsage::has_total_size
 //     Function: MemoryUsage::has_total_size
 //       Access: Public, Static
 //       Access: Public, Static

+ 115 - 43
panda/src/express/memoryUsage.cxx

@@ -29,6 +29,8 @@
 #endif
 #endif
 
 
 #include "memoryUsage.h"
 #include "memoryUsage.h"
+#include "interrogate_request.h"
+
 #if defined(WIN32_VC) && defined(_DEBUG)
 #if defined(WIN32_VC) && defined(_DEBUG)
 #include <crtdbg.h>
 #include <crtdbg.h>
 #endif
 #endif
@@ -41,6 +43,14 @@
 #include <algorithm>
 #include <algorithm>
 #endif
 #endif
 
 
+// This flag is set true in is_counting() mode to indicate that the
+// malloc operation is coming from C++ operator new or delete.
+static bool _is_cpp_operator = false;
+
+// This flag is used to protect the operator new/delete handlers
+// against recursive entry.
+static bool _recursion_protect = false;
+
 MemoryUsage *MemoryUsage::_global_ptr = (MemoryUsage *)NULL;
 MemoryUsage *MemoryUsage::_global_ptr = (MemoryUsage *)NULL;
 
 
 // The cutoff ages, in seconds, for the various buckets in the AgeHistogram.
 // The cutoff ages, in seconds, for the various buckets in the AgeHistogram.
@@ -256,8 +266,24 @@ remove_pointer(ReferenceCount *ptr) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void *MemoryUsage::
 void *MemoryUsage::
 operator_new_handler(size_t size) {
 operator_new_handler(size_t size) {
-  void *ptr = default_operator_new(size);
-  get_global_ptr()->ns_record_void_pointer(ptr, size);
+  void *ptr;
+
+  if (_recursion_protect) {
+    ptr = default_operator_new(size);
+
+  } else {
+    MemoryUsage *mu = get_global_ptr();
+    if (mu->_track_memory_usage) {
+      ptr = default_operator_new(size);
+      get_global_ptr()->ns_record_void_pointer(ptr, size);
+      
+    } else {
+      _is_cpp_operator = true;
+      ptr = default_operator_new(size);
+      _is_cpp_operator = false;
+    }
+  }
+
   return ptr;
   return ptr;
 }
 }
 
 
@@ -272,8 +298,20 @@ operator_new_handler(size_t size) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void MemoryUsage::
 void MemoryUsage::
 operator_delete_handler(void *ptr) {
 operator_delete_handler(void *ptr) {
-  get_global_ptr()->ns_remove_void_pointer(ptr);
-  default_operator_delete(ptr);
+  if (_recursion_protect) {
+    default_operator_delete(ptr);
+
+  } else {
+    MemoryUsage *mu = get_global_ptr();
+    if (mu->_track_memory_usage) {
+      mu->ns_remove_void_pointer(ptr);
+      default_operator_delete(ptr);
+    } else {
+      _is_cpp_operator = true;
+      default_operator_delete(ptr);
+      _is_cpp_operator = false;
+    }
+  }
 }
 }
 
 
 #if defined(WIN32_VC) && defined(_DEBUG)
 #if defined(WIN32_VC) && defined(_DEBUG)
@@ -289,20 +327,38 @@ int MemoryUsage::
 win32_malloc_hook(int alloc_type, void *ptr, 
 win32_malloc_hook(int alloc_type, void *ptr, 
                   size_t size, int block_use, long request, 
                   size_t size, int block_use, long request, 
                   const unsigned char *filename, int line) {
                   const unsigned char *filename, int line) {
-  MemoryUsage *mu = get_global_ptr();
-  if (mu->_count_memory_usage) {
-    switch (alloc_type) {
-    case _HOOK_ALLOC:
-      mu->_total_size += size;
-      break;
-      
-    case _HOOK_REALLOC:
-      mu->_total_size += size - _msize(ptr);
-      break;
+  if (!_recursion_protect) {
+    MemoryUsage *mu = get_global_ptr();
+    if (mu->_count_memory_usage) {
+      int increment = 0;
+      switch (alloc_type) {
+      case _HOOK_ALLOC:
+        increment = size;
+        break;
+        
+      case _HOOK_REALLOC:
+        increment = size - _msize(ptr);
+        break;
+        
+      case _HOOK_FREE:
+        increment = -_msize(ptr);
+        break;
+      }
       
       
-    case _HOOK_FREE:
-      mu->_total_size -= _msize(ptr);
-      break;
+      mu->_total_size += increment;
+
+      /*
+        This isn't working reliably right now.
+      if (_is_cpp_operator) {
+        mu->_cpp_size += increment;
+      }
+      */
+
+#ifdef TRACK_IN_INTERPRETER
+      if (in_interpreter) {
+        mu->_interpreter_size += increment;
+      }
+#endif
     }
     }
   }
   }
 
 
@@ -350,6 +406,8 @@ MemoryUsage() {
 
 
 #if defined(WIN32_VC) && defined(_DEBUG)
 #if defined(WIN32_VC) && defined(_DEBUG)
   if (_count_memory_usage) {
   if (_count_memory_usage) {
+    global_operator_new = &operator_new_handler;
+    global_operator_delete = &operator_delete_handler;
     _CrtSetAllocHook(&win32_malloc_hook);
     _CrtSetAllocHook(&win32_malloc_hook);
   }
   }
 #endif
 #endif
@@ -358,6 +416,7 @@ MemoryUsage() {
   _count = 0;
   _count = 0;
   _current_cpp_size = 0;
   _current_cpp_size = 0;
   _cpp_size = 0;
   _cpp_size = 0;
+  _interpreter_size = 0;
   _total_size = 0;
   _total_size = 0;
 }
 }
 
 
@@ -386,11 +445,11 @@ void MemoryUsage::
 ns_record_pointer(ReferenceCount *ptr) {
 ns_record_pointer(ReferenceCount *ptr) {
   if (_track_memory_usage) {
   if (_track_memory_usage) {
     // We have to protect modifications to the table from recursive
     // We have to protect modifications to the table from recursive
-    // calls by turning off _track_memory_usage while we adjust it.
-    _track_memory_usage = false;
+    // calls by toggling _recursion_protect while we adjust it.
+    _recursion_protect = true;
     pair<Table::iterator, bool> insert_result =
     pair<Table::iterator, bool> insert_result =
       _table.insert(Table::value_type((void *)ptr, MemoryInfo()));
       _table.insert(Table::value_type((void *)ptr, MemoryInfo()));
-    _track_memory_usage = true;
+    _recursion_protect = false;
     
     
     // This shouldn't fail.
     // This shouldn't fail.
     assert(insert_result.first != _table.end());
     assert(insert_result.first != _table.end());
@@ -516,11 +575,11 @@ ns_remove_pointer(ReferenceCount *ptr) {
       double now = TrueClock::get_ptr()->get_real_time();
       double now = TrueClock::get_ptr()->get_real_time();
 
 
       // We have to protect modifications to the table from recursive
       // We have to protect modifications to the table from recursive
-      // calls by turning off _track_memory_usage while we adjust it.
-      _track_memory_usage = false;
+      // calls by toggling _recursion_protect while we adjust it.
+      _recursion_protect = true;
       _trend_types.add_info(info.get_type(), info);
       _trend_types.add_info(info.get_type(), info);
       _trend_ages.add_info(now - info._time, info);
       _trend_ages.add_info(now - info._time, info);
-      _track_memory_usage = true;
+      _recursion_protect = false;
     }
     }
 
 
     if ((info._flags & (MemoryInfo::F_got_ref | MemoryInfo::F_got_void)) == 0) {
     if ((info._flags & (MemoryInfo::F_got_ref | MemoryInfo::F_got_void)) == 0) {
@@ -533,10 +592,10 @@ ns_remove_pointer(ReferenceCount *ptr) {
       _cpp_size -= info._size;
       _cpp_size -= info._size;
 
 
       // We have to protect modifications to the table from recursive
       // We have to protect modifications to the table from recursive
-      // calls by turning off _track_memory_usage while we adjust it.
-      _track_memory_usage = false;
+      // calls by toggling _recursion_protect while we adjust it.
+      _recursion_protect = true;
       _table.erase(ti);
       _table.erase(ti);
-      _track_memory_usage = true;
+      _recursion_protect = false;
     }
     }
   }
   }
 }
 }
@@ -552,13 +611,12 @@ void MemoryUsage::
 ns_record_void_pointer(void *ptr, size_t size) {
 ns_record_void_pointer(void *ptr, size_t size) {
   if (_track_memory_usage) {
   if (_track_memory_usage) {
     // We have to protect modifications to the table from recursive
     // We have to protect modifications to the table from recursive
-    // calls by turning off _track_memory_usage while we adjust it.
-    _track_memory_usage = false;
+    // calls by toggling _recursion_protect while we adjust it.
+    _recursion_protect = true;
     pair<Table::iterator, bool> insert_result =
     pair<Table::iterator, bool> insert_result =
       _table.insert(Table::value_type((void *)ptr, MemoryInfo()));
       _table.insert(Table::value_type((void *)ptr, MemoryInfo()));
-    _track_memory_usage = true;
-    
-    // This shouldn't fail.
+    _recursion_protect = false;
+
     assert(insert_result.first != _table.end());
     assert(insert_result.first != _table.end());
 
 
     if (insert_result.second) {
     if (insert_result.second) {
@@ -636,10 +694,10 @@ ns_remove_void_pointer(void *ptr) {
       _cpp_size -= info._size;
       _cpp_size -= info._size;
 
 
       // We have to protect modifications to the table from recursive
       // We have to protect modifications to the table from recursive
-      // calls by turning off _track_memory_usage while we adjust it.
-      _track_memory_usage = false;
+      // calls by toggling _recursion_protect while we adjust it.
+      _recursion_protect = true;
       _table.erase(ti);
       _table.erase(ti);
-      _track_memory_usage = true;
+      _recursion_protect = false;
     }
     }
   }
   }
 }
 }
@@ -668,6 +726,20 @@ ns_get_cpp_size() {
   return _cpp_size;
   return _cpp_size;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: MemoryUsage::ns_get_interpreter_size
+//       Access: Private
+//  Description: Returns the total number of bytes of allocated memory
+//               while the high-level languange code is running.  This
+//               number is only meaningful if both Panda and the
+//               high-level language are single-threaded, and running
+//               in the same thread.
+////////////////////////////////////////////////////////////////////
+size_t MemoryUsage::
+ns_get_interpreter_size() {
+  return _interpreter_size;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: MemoryUsage::ns_get_total_size
 //     Function: MemoryUsage::ns_get_total_size
 //       Access: Private
 //       Access: Private
@@ -843,8 +915,8 @@ void MemoryUsage::
 ns_show_current_types() {
 ns_show_current_types() {
   nassertv(_track_memory_usage);
   nassertv(_track_memory_usage);
   // We have to protect modifications to the table from recursive
   // We have to protect modifications to the table from recursive
-  // calls by turning off _track_memory_usage while we adjust it.
-  _track_memory_usage = false;
+  // calls by toggling _recursion_protect while we adjust it.
+  _recursion_protect = true;
 
 
   TypeHistogram hist;
   TypeHistogram hist;
   
   
@@ -857,7 +929,7 @@ ns_show_current_types() {
   }
   }
 
 
   hist.show();
   hist.show();
-  _track_memory_usage = true;
+  _recursion_protect = false;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -883,8 +955,8 @@ ns_show_current_ages() {
   nassertv(_track_memory_usage);
   nassertv(_track_memory_usage);
 
 
   // We have to protect modifications to the table from recursive
   // We have to protect modifications to the table from recursive
-  // calls by turning off _track_memory_usage while we adjust it.
-  _track_memory_usage = false;
+  // calls by toggling _recursion_protect while we adjust it.
+  _recursion_protect = true;
 
 
   AgeHistogram hist;
   AgeHistogram hist;
   double now = TrueClock::get_ptr()->get_real_time();
   double now = TrueClock::get_ptr()->get_real_time();
@@ -899,7 +971,7 @@ ns_show_current_ages() {
 
 
   hist.show();
   hist.show();
 
 
-  _track_memory_usage = true;
+  _recursion_protect = false;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -974,10 +1046,10 @@ consolidate_void_ptr(MemoryInfo &info) {
   }
   }
     
     
   // We have to protect modifications to the table from recursive
   // We have to protect modifications to the table from recursive
-  // calls by turning off _track_memory_usage while we adjust it.
-  _track_memory_usage = false;
+  // calls by toggling _recursion_protect while we adjust it.
+  _recursion_protect = true;
   _table.erase(ti);
   _table.erase(ti);
-  _track_memory_usage = true;
+  _recursion_protect = false;
 }
 }
 
 
 
 

+ 6 - 0
panda/src/express/memoryUsage.h

@@ -71,6 +71,8 @@ public:
   INLINE static size_t get_current_cpp_size() { return 0; }
   INLINE static size_t get_current_cpp_size() { return 0; }
   INLINE static bool has_cpp_size() { return false; }
   INLINE static bool has_cpp_size() { return false; }
   INLINE static size_t get_cpp_size() { return 0; }
   INLINE static size_t get_cpp_size() { return 0; }
+  INLINE static bool has_interpreter_size() { return false; }
+  INLINE static size_t get_interpreter_size() { return 0; }
   INLINE static bool has_total_size() { return false; }
   INLINE static bool has_total_size() { return false; }
   INLINE static size_t get_total_size() { return 0; }
   INLINE static size_t get_total_size() { return 0; }
 
 
@@ -91,6 +93,8 @@ PUBLISHED:
   INLINE static size_t get_current_cpp_size();
   INLINE static size_t get_current_cpp_size();
   INLINE static bool has_cpp_size();
   INLINE static bool has_cpp_size();
   INLINE static size_t get_cpp_size();
   INLINE static size_t get_cpp_size();
+  INLINE static bool has_interpreter_size();
+  INLINE static size_t get_interpreter_size();
   INLINE static bool has_total_size();
   INLINE static bool has_total_size();
   INLINE static size_t get_total_size();
   INLINE static size_t get_total_size();
 
 
@@ -123,6 +127,7 @@ private:
 
 
   size_t ns_get_current_cpp_size();
   size_t ns_get_current_cpp_size();
   size_t ns_get_cpp_size();
   size_t ns_get_cpp_size();
+  size_t ns_get_interpreter_size();
   size_t ns_get_total_size();
   size_t ns_get_total_size();
   int ns_get_num_pointers();
   int ns_get_num_pointers();
   void ns_get_pointers(MemoryUsagePointers &result);
   void ns_get_pointers(MemoryUsagePointers &result);
@@ -152,6 +157,7 @@ private:
   int _count;
   int _count;
   size_t _current_cpp_size;
   size_t _current_cpp_size;
   size_t _cpp_size;
   size_t _cpp_size;
+  size_t _interpreter_size;
   size_t _total_size;
   size_t _total_size;
 
 
   class TypeHistogram {
   class TypeHistogram {

+ 9 - 0
panda/src/graph/namedNode.cxx

@@ -24,6 +24,15 @@
 
 
 TypeHandle NamedNode::_type_handle;
 TypeHandle NamedNode::_type_handle;
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: NamedNode::Destructor
+//       Access: Public, Virtual
+//  Description: 
+////////////////////////////////////////////////////////////////////
+NamedNode::
+~NamedNode() {
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NamedNode::make_copy
 //     Function: NamedNode::make_copy
 //       Access: Public, Virtual
 //       Access: Public, Virtual

+ 1 - 0
panda/src/graph/namedNode.h

@@ -36,6 +36,7 @@ PUBLISHED:
 public:
 public:
   INLINE_GRAPH NamedNode(const NamedNode &copy);
   INLINE_GRAPH NamedNode(const NamedNode &copy);
   INLINE_GRAPH void operator = (const NamedNode &copy);
   INLINE_GRAPH void operator = (const NamedNode &copy);
+  virtual ~NamedNode();
 
 
   virtual Node *make_copy() const;
   virtual Node *make_copy() const;
   virtual void output(ostream &out) const;
   virtual void output(ostream &out) const;

+ 9 - 5
panda/src/pstatclient/pStatClient.cxx

@@ -40,8 +40,9 @@
 PStatClient *PStatClient::_global_pstats = NULL;
 PStatClient *PStatClient::_global_pstats = NULL;
 
 
 #ifndef CPPPARSER
 #ifndef CPPPARSER
-PStatCollector _memory_usage_pcollector("Memory usage");
-PStatCollector _cpp_usage_pcollector("Memory usage:C++");
+PStatCollector _total_size_pcollector("Memory usage");
+PStatCollector _cpp_size_pcollector("Memory usage:C++");
+PStatCollector _interpreter_size_pcollector("Memory usage:Interpreter");
 #endif
 #endif
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -372,11 +373,14 @@ main_tick() {
   // code inside the MemoryUsage class, where it fits a little better,
   // code inside the MemoryUsage class, where it fits a little better,
   // simply because MemoryUsage is a very low-level class that doesn't
   // simply because MemoryUsage is a very low-level class that doesn't
   // know about PStatClient.
   // know about PStatClient.
+  if (MemoryUsage::has_total_size()) {
+    _total_size_pcollector.set_level(MemoryUsage::get_total_size());
+  }
   if (MemoryUsage::has_cpp_size()) {
   if (MemoryUsage::has_cpp_size()) {
-    _cpp_usage_pcollector.set_level(MemoryUsage::get_cpp_size());
+    _cpp_size_pcollector.set_level(MemoryUsage::get_cpp_size());
   }
   }
-  if (MemoryUsage::has_total_size()) {
-    _memory_usage_pcollector.set_level(MemoryUsage::get_total_size());
+  if (MemoryUsage::has_interpreter_size()) {
+    _interpreter_size_pcollector.set_level(MemoryUsage::get_interpreter_size());
   }
   }
 
 
   get_global_pstats()->get_main_thread().new_frame();
   get_global_pstats()->get_main_thread().new_frame();

+ 2 - 1
panda/src/pstatclient/pStatProperties.cxx

@@ -147,8 +147,9 @@ static LevelCollectorProperties level_properties[] = {
   { 1, "State changes",                    { 1.0, 0.5, 0.2 },  "", 500.0 },
   { 1, "State changes",                    { 1.0, 0.5, 0.2 },  "", 500.0 },
   { 1, "State changes:Transforms",         { 0.2, 0.2, 0.8 } },
   { 1, "State changes:Transforms",         { 0.2, 0.2, 0.8 } },
   { 1, "State changes:Textures",           { 0.8, 0.2, 0.2 } },
   { 1, "State changes:Textures",           { 0.8, 0.2, 0.2 } },
-  { 1, "Memory usage",                     { 0.8, 0.2, 0.5 },  "MB", 64, 1048576 },
+  { 1, "Memory usage",                     { 0.5, 1.0, 0.5 },  "MB", 64, 1048576 },
   { 1, "Memory usage:C++",                 { 0.2, 0.2, 1.0 } },
   { 1, "Memory usage:C++",                 { 0.2, 0.2, 1.0 } },
+  { 1, "Memory usage:Interpreter",         { 0.8, 0.2, 0.5 } },
   { 0, NULL }
   { 0, NULL }
 };
 };