general: make DO_MEMORY_USAGE setting not change ABI compatibility

This commit is contained in:
rdb 2017-07-10 19:50:09 +02:00
parent 5fffbbce47
commit 925ce854d0
27 changed files with 333 additions and 127 deletions

View File

@ -202,13 +202,11 @@ MemoryHook() {
#endif // WIN32
#ifdef DO_MEMORY_USAGE
_total_heap_single_size = 0;
_total_heap_array_size = 0;
_requested_heap_size = 0;
_total_mmap_size = 0;
_max_heap_size = ~(size_t)0;
#endif
}
/**
@ -216,19 +214,16 @@ MemoryHook() {
*/
MemoryHook::
MemoryHook(const MemoryHook &copy) :
_page_size(copy._page_size)
{
#ifdef DO_MEMORY_USAGE
_total_heap_single_size = copy._total_heap_single_size;
_total_heap_array_size = copy._total_heap_array_size;
_requested_heap_size = copy._requested_heap_size;
_total_mmap_size = copy._total_mmap_size;
_max_heap_size = copy._max_heap_size;
#endif
_page_size(copy._page_size),
_total_heap_single_size(copy._total_heap_single_size),
_total_heap_array_size(copy._total_heap_array_size),
_requested_heap_size(copy._requested_heap_size),
_total_mmap_size(copy._total_mmap_size),
_max_heap_size(copy._max_heap_size) {
((MutexImpl &)copy._lock).acquire();
copy._lock.acquire();
_deleted_chains = copy._deleted_chains;
((MutexImpl &)copy._lock).release();
copy._lock.release();
}
/**
@ -631,7 +626,6 @@ alloc_fail(size_t attempted_size) {
abort();
}
#ifdef DO_MEMORY_USAGE
/**
* This callback method is called whenever the total allocated heap size
* exceeds _max_heap_size. It's mainly intended for reporting memory leaks,
@ -642,6 +636,7 @@ alloc_fail(size_t attempted_size) {
*/
void MemoryHook::
overflow_heap_size() {
#ifdef DO_MEMORY_USAGE
_max_heap_size = ~(size_t)0;
}
#endif // DO_MEMORY_USAGE
}

View File

@ -67,7 +67,6 @@ public:
INLINE static size_t get_ptr_size(void *ptr);
#ifdef DO_MEMORY_USAGE
protected:
TVOLATILE AtomicAdjust::Integer _total_heap_single_size;
TVOLATILE AtomicAdjust::Integer _total_heap_array_size;
@ -79,7 +78,6 @@ protected:
size_t _max_heap_size;
virtual void overflow_heap_size();
#endif // DO_MEMORY_USAGE
private:
size_t _page_size;
@ -87,7 +85,7 @@ private:
typedef map<size_t, DeletedBufferChain *> DeletedChains;
DeletedChains _deleted_chains;
MutexImpl _lock;
mutable MutexImpl _lock;
};
#include "memoryHook.I"

View File

@ -26,9 +26,7 @@ TypeRegistryNode(TypeHandle handle, const string &name, TypeHandle &ref) :
_handle(handle), _name(name), _ref(ref)
{
clear_subtree();
#ifdef DO_MEMORY_USAGE
memset(_memory_usage, 0, sizeof(_memory_usage));
#endif
}
/**

View File

@ -47,9 +47,7 @@ public:
Classes _parent_classes;
Classes _child_classes;
#ifdef DO_MEMORY_USAGE
AtomicAdjust::Integer _memory_usage[TypeHandle::MC_limit];
#endif
static bool _paranoid_inheritance;

View File

@ -75,6 +75,9 @@ private:
#include "memoryInfo.I"
#else
class MemoryInfo;
#endif // DO_MEMORY_USAGE
#endif

View File

@ -16,9 +16,13 @@
* to true, indicating that this class will be in effect. If this returns
* false, the user has indicated not to do any of this.
*/
INLINE bool MemoryUsage::
ALWAYS_INLINE bool MemoryUsage::
get_track_memory_usage() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_track_memory_usage;
#else
return false;
#endif
}
/**
@ -26,7 +30,19 @@ get_track_memory_usage() {
*/
INLINE void MemoryUsage::
record_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_record_pointer(ptr);
#endif
}
/**
* Indicates that the given pointer has been recently allocated.
*/
INLINE void MemoryUsage::
record_pointer(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_record_pointer(ptr, type);
#endif
}
/**
@ -37,7 +53,9 @@ record_pointer(ReferenceCount *ptr) {
*/
INLINE void MemoryUsage::
update_type(ReferenceCount *ptr, TypeHandle type) {
get_global_ptr()->ns_update_type(ptr, type);
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type((void *)ptr, type);
#endif
}
/**
@ -48,7 +66,21 @@ update_type(ReferenceCount *ptr, TypeHandle type) {
*/
INLINE void MemoryUsage::
update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
get_global_ptr()->ns_update_type(ptr, typed_ptr);
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type((void *)ptr, typed_ptr);
#endif
}
/**
* Associates the indicated type with the given pointer. This should be
* called by functions (e.g. the constructor) that know more specifically
* what type of thing we've got.
*/
INLINE void MemoryUsage::
update_type(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_update_type(ptr, type);
#endif
}
/**
@ -56,7 +88,9 @@ update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
*/
INLINE void MemoryUsage::
remove_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_remove_pointer(ptr);
#endif
}
/**
@ -65,7 +99,11 @@ remove_pointer(ReferenceCount *ptr) {
*/
INLINE bool MemoryUsage::
is_tracking() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_track_memory_usage;
#else
return false;
#endif
}
/**
@ -75,7 +113,11 @@ is_tracking() {
*/
INLINE bool MemoryUsage::
is_counting() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_count_memory_usage;
#else
return false;
#endif
}
/**
@ -84,7 +126,11 @@ is_counting() {
*/
INLINE size_t MemoryUsage::
get_current_cpp_size() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_current_cpp_size;
#else
return 0;
#endif
}
/**
@ -93,7 +139,11 @@ get_current_cpp_size() {
*/
INLINE size_t MemoryUsage::
get_total_cpp_size() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->_total_cpp_size;
#else
return 0;
#endif
}
/**
@ -102,7 +152,11 @@ get_total_cpp_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_single_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_single_size);
#else
return 0;
#endif
}
/**
@ -111,7 +165,11 @@ get_panda_heap_single_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_array_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_heap_array_size);
#else
return 0;
#endif
}
/**
@ -121,7 +179,7 @@ get_panda_heap_array_size() {
*/
INLINE size_t MemoryUsage::
get_panda_heap_overhead() {
#if defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2)
#if defined(DO_MEMORY_USAGE) && (defined(USE_MEMORY_DLMALLOC) || defined(USE_MEMORY_PTMALLOC2))
MemoryUsage *mu = get_global_ptr();
return (size_t)(AtomicAdjust::get(mu->_requested_heap_size) - AtomicAdjust::get(mu->_total_heap_single_size) - AtomicAdjust::get(mu->_total_heap_array_size));
#else
@ -135,7 +193,11 @@ get_panda_heap_overhead() {
*/
INLINE size_t MemoryUsage::
get_panda_mmap_size() {
#ifdef DO_MEMORY_USAGE
return (size_t)AtomicAdjust::get(get_global_ptr()->_total_mmap_size);
#else
return 0;
#endif
}
/**
@ -152,6 +214,7 @@ get_panda_mmap_size() {
*/
INLINE size_t MemoryUsage::
get_external_size() {
#ifdef DO_MEMORY_USAGE
MemoryUsage *mu = get_global_ptr();
if (mu->_count_memory_usage) {
// We can only possibly know this with memory counting, which tracks every
@ -169,6 +232,9 @@ get_external_size() {
} else {
return 0;
}
#else
return 0;
#endif
}
/**
@ -177,6 +243,7 @@ get_external_size() {
*/
INLINE size_t MemoryUsage::
get_total_size() {
#ifdef DO_MEMORY_USAGE
MemoryUsage *mu = get_global_ptr();
if (mu->_count_memory_usage) {
return mu->_total_size + (size_t)mu->_requested_heap_size;
@ -187,6 +254,9 @@ get_total_size() {
return (size_t)(AtomicAdjust::get(mu->_total_heap_single_size) + AtomicAdjust::get(mu->_total_heap_array_size));
#endif
}
#else
return 0;
#endif
}
/**
@ -194,7 +264,11 @@ get_total_size() {
*/
INLINE int MemoryUsage::
get_num_pointers() {
#ifdef DO_MEMORY_USAGE
return get_global_ptr()->ns_get_num_pointers();
#else
return 0;
#endif
}
/**
@ -203,7 +277,9 @@ get_num_pointers() {
*/
INLINE void MemoryUsage::
get_pointers(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers(result);
#endif
}
/**
@ -212,7 +288,9 @@ get_pointers(MemoryUsagePointers &result) {
*/
INLINE void MemoryUsage::
get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_of_type(result, type);
#endif
}
/**
@ -221,7 +299,9 @@ get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
*/
INLINE void MemoryUsage::
get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_of_age(result, from, to);
#endif
}
/**
@ -242,7 +322,9 @@ get_pointers_of_age(MemoryUsagePointers &result, double from, double to) {
*/
INLINE void MemoryUsage::
get_pointers_with_zero_count(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_get_pointers_with_zero_count(result);
#endif
}
/**
@ -253,7 +335,9 @@ get_pointers_with_zero_count(MemoryUsagePointers &result) {
*/
INLINE void MemoryUsage::
freeze() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_freeze();
#endif
}
/**
@ -261,7 +345,9 @@ freeze() {
*/
INLINE void MemoryUsage::
show_current_types() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_current_types();
#endif
}
/**
@ -270,7 +356,9 @@ show_current_types() {
*/
INLINE void MemoryUsage::
show_trend_types() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_trend_types();
#endif
}
/**
@ -278,7 +366,9 @@ show_trend_types() {
*/
INLINE void MemoryUsage::
show_current_ages() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_current_ages();
#endif
}
/**
@ -287,7 +377,9 @@ show_current_ages() {
*/
INLINE void MemoryUsage::
show_trend_ages() {
#ifdef DO_MEMORY_USAGE
get_global_ptr()->ns_show_trend_ages();
#endif
}
/**
@ -295,6 +387,7 @@ show_trend_ages() {
*/
INLINE MemoryUsage *MemoryUsage::
get_global_ptr() {
#ifdef DO_MEMORY_USAGE
#ifdef __GNUC__
// Tell the compiler that this is an unlikely branch.
if (__builtin_expect(_global_ptr == nullptr, 0)) {
@ -305,4 +398,7 @@ get_global_ptr() {
}
return _global_ptr;
#else
return nullptr;
#endif
}

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsage.h"
#ifdef DO_MEMORY_USAGE
#include "memoryUsagePointers.h"
#include "trueClock.h"
#include "typedReferenceCount.h"
@ -45,16 +42,17 @@ double MemoryUsage::AgeHistogram::_cutoff[MemoryUsage::AgeHistogram::num_buckets
60.0,
};
/**
* Adds a single entry to the histogram.
*/
void MemoryUsage::TypeHistogram::
add_info(TypeHandle type, MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
_counts[type].add_info(info);
#endif
}
#ifdef DO_MEMORY_USAGE
// This class is a temporary class used only in TypeHistogram::show(), below,
// to sort the types in descending order by counts.
class TypeHistogramCountSorter {
@ -71,12 +69,14 @@ public:
MemoryUsagePointerCounts _count;
TypeHandle _type;
};
#endif
/**
* Shows the contents of the histogram to nout.
*/
void MemoryUsage::TypeHistogram::
show() const {
#ifdef DO_MEMORY_USAGE
// First, copy the relevant information to a vector so we can sort by
// counts. Don't use a pvector.
typedef vector<TypeHistogramCountSorter> CountSorter;
@ -99,6 +99,7 @@ show() const {
}
nout << " : " << (*vi)._count << "\n";
}
#endif
}
/**
@ -122,9 +123,11 @@ AgeHistogram() {
*/
void MemoryUsage::AgeHistogram::
add_info(double age, MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
int bucket = choose_bucket(age);
nassertv(bucket >= 0 && bucket < num_buckets);
_counts[bucket].add_info(info);
#endif
}
/**
@ -132,6 +135,7 @@ add_info(double age, MemoryInfo *info) {
*/
void MemoryUsage::AgeHistogram::
show() const {
#ifdef DO_MEMORY_USAGE
for (int i = 0; i < num_buckets - 1; i++) {
nout << _cutoff[i] << " to " << _cutoff[i + 1] << " seconds old : ";
_counts[i].output(nout);
@ -140,6 +144,7 @@ show() const {
nout << _cutoff[num_buckets - 1] << " seconds old and up : ";
_counts[num_buckets - 1].output(nout);
nout << "\n";
#endif
}
/**
@ -147,9 +152,11 @@ show() const {
*/
void MemoryUsage::AgeHistogram::
clear() {
#ifdef DO_MEMORY_USAGE
for (int i = 0; i < num_buckets; i++) {
_counts[i].clear();
}
#endif
}
/**
@ -157,6 +164,7 @@ clear() {
*/
int MemoryUsage::AgeHistogram::
choose_bucket(double age) const {
#ifdef DO_MEMORY_USAGE
for (int i = num_buckets - 1; i >= 0; i--) {
if (age >= _cutoff[i]) {
return i;
@ -164,6 +172,7 @@ choose_bucket(double age) const {
}
express_cat.error()
<< "No suitable bucket for age " << age << "\n";
#endif
return 0;
}
@ -173,6 +182,7 @@ choose_bucket(double age) const {
*/
void *MemoryUsage::
heap_alloc_single(size_t size) {
#ifdef DO_MEMORY_USAGE
void *ptr;
if (_recursion_protect) {
@ -202,6 +212,9 @@ heap_alloc_single(size_t size) {
}
return ptr;
#else
return MemoryHook::heap_alloc_single(size);
#endif
}
/**
@ -209,6 +222,7 @@ heap_alloc_single(size_t size) {
*/
void MemoryUsage::
heap_free_single(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -231,6 +245,9 @@ heap_free_single(void *ptr) {
MemoryHook::heap_free_single(ptr);
}
}
#else
MemoryHook::heap_free_single(ptr);
#endif
}
/**
@ -239,6 +256,7 @@ heap_free_single(void *ptr) {
*/
void *MemoryUsage::
heap_alloc_array(size_t size) {
#ifdef DO_MEMORY_USAGE
void *ptr;
if (_recursion_protect) {
@ -268,6 +286,9 @@ heap_alloc_array(size_t size) {
}
return ptr;
#else
return MemoryHook::heap_alloc_array(size);
#endif
}
/**
@ -275,6 +296,7 @@ heap_alloc_array(size_t size) {
*/
void *MemoryUsage::
heap_realloc_array(void *ptr, size_t size) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
ptr = MemoryHook::heap_realloc_array(ptr, size);
if (express_cat.is_spam()) {
@ -303,6 +325,9 @@ heap_realloc_array(void *ptr, size_t size) {
}
return ptr;
#else
return MemoryHook::heap_realloc_array(ptr, size);
#endif
}
/**
@ -310,6 +335,7 @@ heap_realloc_array(void *ptr, size_t size) {
*/
void MemoryUsage::
heap_free_array(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -332,6 +358,9 @@ heap_free_array(void *ptr) {
MemoryHook::heap_free_array(ptr);
}
}
#else
MemoryHook::heap_free_array(ptr);
#endif
}
/**
@ -343,6 +372,7 @@ heap_free_array(void *ptr) {
*/
void MemoryUsage::
mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
#ifdef DO_MEMORY_USAGE
if (_recursion_protect || !_track_memory_usage) {
return;
}
@ -391,6 +421,7 @@ mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
// We're removing this pointer from use.
ns_remove_void_pointer(ptr);
}
#endif
}
#if (defined(WIN32_VC) || defined (WIN64_VC))&& defined(_DEBUG)
@ -430,7 +461,23 @@ win32_malloc_hook(int alloc_type, void *ptr,
*
*/
MemoryUsage::
MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
MemoryUsage(const MemoryHook &copy) :
MemoryHook(copy),
_info_set_dirty(false),
_freeze_index(0),
_count(0),
_current_cpp_size(0),
_total_cpp_size(0),
_total_size(0),
_track_memory_usage(false),
_startup_track_memory_usage(false),
_count_memory_usage(false),
_report_memory_usage(false),
_report_memory_interval(0.0),
_last_report_time(0.0) {
#ifdef DO_MEMORY_USAGE
// We must get these variables here instead of in config_express.cxx,
// because we need to know it at static init time, and who knows when the
// code in config_express will be executed.
@ -456,9 +503,6 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
("report-memory-interval", 5.0,
PRC_DESC("This is the interval, in seconds, for reports of currently allocated "
"memory, when report-memory-usage is true."));
_last_report_time = 0.0;
_count_memory_usage = false;
int64_t max_heap_size = ConfigVariableInt64
("max-heap-size", 0,
@ -480,13 +524,7 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
_CrtSetAllocHook(&win32_malloc_hook);
_count_memory_usage = true;
#endif
_info_set_dirty = false;
_freeze_index = 0;
_count = 0;
_current_cpp_size = 0;
_total_cpp_size = 0;
_total_size = 0;
#endif // DO_MEMORY_USAGE
}
/**
@ -494,9 +532,16 @@ MemoryUsage(const MemoryHook &copy) : MemoryHook(copy) {
*/
void MemoryUsage::
init_memory_usage() {
#ifdef DO_MEMORY_USAGE
init_memory_hook();
_global_ptr = new MemoryUsage(*memory_hook);
memory_hook = _global_ptr;
#else
// If this gets called, we still need to initialize the global_ptr with a
// stub even if we don't compile with memory usage tracking enabled, for ABI
// stability. However, we won't replace the memory hook.
_global_ptr = new MemoryUsage(*memory_hook);
#endif
}
/**
@ -507,6 +552,7 @@ init_memory_usage() {
*/
void MemoryUsage::
overflow_heap_size() {
#ifdef DO_MEMORY_USAGE
MemoryHook::overflow_heap_size();
express_cat.error()
@ -524,6 +570,7 @@ overflow_heap_size() {
// Turn on spamful debugging.
_track_memory_usage = true;
_report_memory_usage = true;
#endif
}
/**
@ -531,12 +578,13 @@ overflow_heap_size() {
*/
void MemoryUsage::
ns_record_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
// We have to protect modifications to the table from recursive calls by
// toggling _recursion_protect while we adjust it.
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
_table.insert(Table::value_type((void *)ptr, nullptr));
// This shouldn't fail.
assert(insert_result.first != _table.end());
@ -575,6 +623,61 @@ ns_record_pointer(ReferenceCount *ptr) {
}
}
}
#endif
}
/**
* Indicates that the given pointer has been recently allocated.
*/
void MemoryUsage::
ns_record_pointer(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
// We have to protect modifications to the table from recursive calls by
// toggling _recursion_protect while we adjust it.
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type(ptr, nullptr));
// This shouldn't fail.
assert(insert_result.first != _table.end());
if (insert_result.second) {
(*insert_result.first).second = new MemoryInfo;
_info_set_dirty = true;
++_count;
}
MemoryInfo *info = (*insert_result.first).second;
// We should already have a pointer, thanks to a previous call to
// mark_pointer().
nassertv(info->_void_ptr == ptr && info->_ref_ptr == nullptr);
info->_void_ptr = ptr;
info->_static_type = type;
info->_dynamic_type = type;
info->_time = TrueClock::get_global_ptr()->get_long_time();
info->_freeze_index = _freeze_index;
info->_flags |= MemoryInfo::F_reconsider_dynamic_type;
// We close the recursion_protect flag all the way down here, so that we
// also protect ourselves against a possible recursive call in
// TrueClock::get_global_ptr().
_recursion_protect = false;
if (_report_memory_usage) {
double now = TrueClock::get_global_ptr()->get_long_time();
if (now - _last_report_time > _report_memory_interval) {
_last_report_time = now;
express_cat.info()
<< "*** Current memory usage: " << get_total_size() << "\n";
show_current_types();
}
}
}
#endif
}
/**
@ -584,7 +687,8 @@ ns_record_pointer(ReferenceCount *ptr) {
* only that it's a "ReferenceCount".
*/
void MemoryUsage::
ns_update_type(ReferenceCount *ptr, TypeHandle type) {
ns_update_type(void *ptr, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -592,7 +696,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
if (_startup_track_memory_usage) {
express_cat.error()
<< "Attempt to update type to " << type << " for unrecorded pointer "
<< (void *)ptr << "!\n";
<< ptr << "!\n";
nassertv(false);
}
return;
@ -605,6 +709,7 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
consolidate_void_ptr(info);
}
#endif
}
/**
@ -614,7 +719,8 @@ ns_update_type(ReferenceCount *ptr, TypeHandle type) {
* the pointer as a TypedObject it doesn't need any more help.
*/
void MemoryUsage::
ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
ns_update_type(void *ptr, TypedObject *typed_ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -623,7 +729,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
express_cat.error()
<< "Attempt to update type to " << typed_ptr->get_type()
<< " for unrecorded pointer "
<< (void *)ptr << "!\n";
<< ptr << "!\n";
}
return;
}
@ -634,6 +740,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
consolidate_void_ptr(info);
}
#endif
}
/**
@ -641,6 +748,7 @@ ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr) {
*/
void MemoryUsage::
ns_remove_pointer(ReferenceCount *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
Table::iterator ti;
ti = _table.find(ptr);
@ -705,6 +813,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
}
}
}
#endif
}
/**
@ -713,6 +822,7 @@ ns_remove_pointer(ReferenceCount *ptr) {
*/
void MemoryUsage::
ns_record_void_pointer(void *ptr, size_t size) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -724,7 +834,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
_recursion_protect = true;
pair<Table::iterator, bool> insert_result =
_table.insert(Table::value_type((void *)ptr, (MemoryInfo *)NULL));
_table.insert(Table::value_type((void *)ptr, nullptr));
assert(insert_result.first != _table.end());
@ -761,6 +871,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
// TrueClock::get_global_ptr().
_recursion_protect = false;
}
#endif
}
/**
@ -768,6 +879,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
*/
void MemoryUsage::
ns_remove_void_pointer(void *ptr) {
#ifdef DO_MEMORY_USAGE
if (_track_memory_usage) {
if (express_cat.is_spam()) {
express_cat.spam()
@ -823,6 +935,7 @@ ns_remove_void_pointer(void *ptr) {
_info_set_dirty = true;
delete info;
}
#endif
}
/**
@ -830,8 +943,12 @@ ns_remove_void_pointer(void *ptr) {
*/
int MemoryUsage::
ns_get_num_pointers() {
#ifdef DO_MEMORY_USAGE
nassertr(_track_memory_usage, 0);
return _count;
#else
return 0;
#endif
}
/**
@ -840,6 +957,7 @@ ns_get_num_pointers() {
*/
void MemoryUsage::
ns_get_pointers(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -857,6 +975,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
now - info->_time);
}
}
#endif
}
/**
@ -865,6 +984,7 @@ ns_get_pointers(MemoryUsagePointers &result) {
*/
void MemoryUsage::
ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -886,6 +1006,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
}
}
}
#endif
}
/**
@ -895,6 +1016,7 @@ ns_get_pointers_of_type(MemoryUsagePointers &result, TypeHandle type) {
void MemoryUsage::
ns_get_pointers_of_age(MemoryUsagePointers &result,
double from, double to) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -915,6 +1037,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
}
}
}
#endif
}
/**
@ -935,6 +1058,7 @@ ns_get_pointers_of_age(MemoryUsagePointers &result,
*/
void MemoryUsage::
ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
result.clear();
@ -955,6 +1079,7 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
}
}
}
#endif
}
/**
@ -965,11 +1090,13 @@ ns_get_pointers_with_zero_count(MemoryUsagePointers &result) {
*/
void MemoryUsage::
ns_freeze() {
#ifdef DO_MEMORY_USAGE
_count = 0;
_current_cpp_size = 0;
_trend_types.clear();
_trend_ages.clear();
_freeze_index++;
#endif
}
/**
@ -977,6 +1104,7 @@ ns_freeze() {
*/
void MemoryUsage::
ns_show_current_types() {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
TypeHistogram hist;
@ -994,6 +1122,7 @@ ns_show_current_types() {
}
hist.show();
_recursion_protect = false;
#endif
}
/**
@ -1002,7 +1131,9 @@ ns_show_current_types() {
*/
void MemoryUsage::
ns_show_trend_types() {
#ifdef DO_MEMORY_USAGE
_trend_types.show();
#endif
}
/**
@ -1010,6 +1141,7 @@ ns_show_trend_types() {
*/
void MemoryUsage::
ns_show_current_ages() {
#ifdef DO_MEMORY_USAGE
nassertv(_track_memory_usage);
AgeHistogram hist;
@ -1026,6 +1158,7 @@ ns_show_current_ages() {
hist.show();
_recursion_protect = false;
#endif
}
/**
@ -1037,6 +1170,8 @@ ns_show_trend_ages() {
_trend_ages.show();
}
#ifdef DO_MEMORY_USAGE
/**
* If the size information has not yet been determined for this pointer,
* checks to see if it has possibly been recorded under the TypedObject
@ -1126,5 +1261,4 @@ refresh_info_set() {
_info_set_dirty = false;
}
#endif // DO_MEMORY_USAGE

View File

@ -15,9 +15,6 @@
#define MEMORYUSAGE_H
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
#include "typedObject.h"
#include "memoryInfo.h"
#include "memoryUsagePointerCounts.h"
@ -33,18 +30,22 @@ class MemoryUsagePointers;
* every such object currently allocated.
*
* When compiled with NDEBUG set, this entire class does nothing and compiles
* to nothing.
* to a stub.
*/
class EXPCL_PANDAEXPRESS MemoryUsage : public MemoryHook {
public:
INLINE static bool get_track_memory_usage();
ALWAYS_INLINE static bool get_track_memory_usage();
INLINE static void record_pointer(ReferenceCount *ptr);
INLINE static void record_pointer(void *ptr, TypeHandle type);
INLINE static void update_type(ReferenceCount *ptr, TypeHandle type);
INLINE static void update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
INLINE static void update_type(void *ptr, TypeHandle type);
INLINE static void remove_pointer(ReferenceCount *ptr);
public:
protected:
// These are not marked public, but they can be accessed via the MemoryHook
// base class.
virtual void *heap_alloc_single(size_t size);
virtual void heap_free_single(void *ptr);
@ -98,8 +99,9 @@ private:
static void init_memory_usage();
void ns_record_pointer(ReferenceCount *ptr);
void ns_update_type(ReferenceCount *ptr, TypeHandle type);
void ns_update_type(ReferenceCount *ptr, TypedObject *typed_ptr);
void ns_record_pointer(void *ptr, TypeHandle type);
void ns_update_type(void *ptr, TypeHandle type);
void ns_update_type(void *ptr, TypedObject *typed_ptr);
void ns_remove_pointer(ReferenceCount *ptr);
void ns_record_void_pointer(void *ptr, size_t size);
@ -120,8 +122,10 @@ private:
void ns_show_current_ages();
void ns_show_trend_ages();
#ifdef DO_MEMORY_USAGE
void consolidate_void_ptr(MemoryInfo *info);
void refresh_info_set();
#endif
static MemoryUsage *_global_ptr;
@ -196,6 +200,4 @@ private:
#include "memoryUsage.I"
#endif // DO_MEMORY_USAGE
#endif

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsagePointerCounts.h"
#ifdef DO_MEMORY_USAGE
#include "memoryInfo.h"
/**
@ -22,6 +19,7 @@
*/
void MemoryUsagePointerCounts::
add_info(MemoryInfo *info) {
#ifdef DO_MEMORY_USAGE
_count++;
if (info->is_size_known()) {
@ -29,6 +27,7 @@ add_info(MemoryInfo *info) {
} else {
_unknown_size_count++;
}
#endif
}
/**
@ -36,6 +35,7 @@ add_info(MemoryInfo *info) {
*/
void MemoryUsagePointerCounts::
output(ostream &out) const {
#ifdef DO_MEMORY_USAGE
out << _count << " pointers";
if (_unknown_size_count < _count) {
out << ", ";
@ -48,6 +48,7 @@ output(ostream &out) const {
out << " (" << _unknown_size_count << " of unknown size)";
}
}
#endif
}
/**
@ -56,6 +57,7 @@ output(ostream &out) const {
*/
void MemoryUsagePointerCounts::
output_bytes(ostream &out, size_t size) {
#ifdef DO_MEMORY_USAGE
if (size < 4 * 1024) {
out << size << " bytes";
@ -65,6 +67,5 @@ output_bytes(ostream &out, size_t size) {
} else {
out << size / (1024 * 1024) << " Mb";
}
#endif
}
#endif // DO_MEMORY_USAGE

View File

@ -16,8 +16,6 @@
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
class MemoryInfo;
/**
@ -55,6 +53,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointerCounts &c);
#include "memoryUsagePointerCounts.I"
#endif // DO_MEMORY_USAGE
#endif

View File

@ -12,9 +12,6 @@
*/
#include "memoryUsagePointers.h"
#ifdef DO_MEMORY_USAGE
#include "config_express.h"
#include "referenceCount.h"
#include "typedReferenceCount.h"
@ -38,7 +35,11 @@ MemoryUsagePointers::
*/
size_t MemoryUsagePointers::
get_num_pointers() const {
#ifdef DO_MEMORY_USAGE
return _entries.size();
#else
return 0;
#endif
}
/**
@ -46,21 +47,26 @@ get_num_pointers() const {
*/
ReferenceCount *MemoryUsagePointers::
get_pointer(size_t n) const {
nassertr(n < get_num_pointers(), NULL);
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), nullptr);
return _entries[n]._ref_ptr;
#else
return nullptr;
#endif
}
/**
* Returns the nth pointer of the set, typecast to a TypedObject if possible.
* If the pointer is not a TypedObject or if the cast cannot be made, returns
* NULL.
* nullptr.
*/
TypedObject *MemoryUsagePointers::
get_typed_pointer(size_t n) const {
nassertr(n < get_num_pointers(), NULL);
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), nullptr);
TypedObject *typed_ptr = _entries[n]._typed_ptr;
if (typed_ptr != (TypedObject *)NULL) {
if (typed_ptr != nullptr) {
return typed_ptr;
}
@ -85,7 +91,8 @@ get_typed_pointer(size_t n) const {
type.is_derived_from(TypedReferenceCount::get_class_type())) {
return (TypedReferenceCount *)ref_ptr;
}
return NULL;
#endif
return nullptr;
}
/**
@ -93,8 +100,12 @@ get_typed_pointer(size_t n) const {
*/
TypeHandle MemoryUsagePointers::
get_type(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), TypeHandle::none());
return _entries[n]._type;
#else
return TypeHandle::none();
#endif
}
/**
@ -102,8 +113,12 @@ get_type(size_t n) const {
*/
string MemoryUsagePointers::
get_type_name(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), "");
return get_type(n).get_name();
#else
return "";
#endif
}
/**
@ -113,8 +128,12 @@ get_type_name(size_t n) const {
*/
double MemoryUsagePointers::
get_age(size_t n) const {
#ifdef DO_MEMORY_USAGE
nassertr(n < get_num_pointers(), 0.0);
return _entries[n]._age;
#else
return 0.0;
#endif
}
/**
@ -122,7 +141,9 @@ get_age(size_t n) const {
*/
void MemoryUsagePointers::
clear() {
#ifdef DO_MEMORY_USAGE
_entries.clear();
#endif
}
/**
@ -130,7 +151,9 @@ clear() {
*/
void MemoryUsagePointers::
output(ostream &out) const {
#ifdef DO_MEMORY_USAGE
out << _entries.size() << " pointers.";
#endif
}
/**
@ -139,13 +162,12 @@ output(ostream &out) const {
void MemoryUsagePointers::
add_entry(ReferenceCount *ref_ptr, TypedObject *typed_ptr,
TypeHandle type, double age) {
#ifdef DO_MEMORY_USAGE
// We can't safely add pointers with a zero reference count. They might be
// statically-allocated or something, and if we try to add them they'll try
// to destruct when the PointerTo later goes away.
if (ref_ptr->get_ref_count() != 0) {
_entries.push_back(Entry(ref_ptr, typed_ptr, type, age));
}
#endif
}
#endif // DO_MEMORY_USAGE

View File

@ -15,9 +15,6 @@
#define MEMORYUSAGEPOINTERS_H
#include "pandabase.h"
#ifdef DO_MEMORY_USAGE
#include "typedObject.h"
#include "pointerTo.h"
#include "referenceCount.h"
@ -53,7 +50,9 @@ PUBLISHED:
string get_type_name(size_t n) const;
double get_age(size_t n) const;
#ifdef DO_MEMORY_USAGE
EXTENSION(PyObject *get_python_pointer(size_t n) const);
#endif
void clear();
@ -94,6 +93,4 @@ INLINE ostream &operator << (ostream &out, const MemoryUsagePointers &mup) {
#include "memoryUsagePointers.I"
#endif // MEMORY_USAGE_POINTERS
#endif

View File

@ -141,7 +141,6 @@ reassign(const PointerToBase<To> &copy) {
}
}
#ifdef DO_MEMORY_USAGE
/**
* Ensures that the MemoryUsage record for the pointer has the right type of
* object, if we know the type ourselves.
@ -149,6 +148,7 @@ reassign(const PointerToBase<To> &copy) {
template<class T>
INLINE void PointerToBase<T>::
update_type(To *ptr) {
#ifdef DO_MEMORY_USAGE
if (MemoryUsage::get_track_memory_usage()) {
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
@ -159,9 +159,8 @@ update_type(To *ptr) {
MemoryUsage::update_type(ptr, type);
}
}
}
#endif // DO_MEMORY_USAGE
}
/**
* A convenient way to set the PointerTo object to NULL. (Assignment to a NULL

View File

@ -44,9 +44,7 @@ protected:
INLINE void reassign(To *ptr);
INLINE void reassign(const PointerToBase<To> &copy);
#ifdef DO_MEMORY_USAGE
INLINE void update_type(To *ptr);
#endif // DO_MEMORY_USAGE
// No assignment or retrieval functions are declared in PointerToBase,
// because we will have to specialize on const vs. non-const later.

View File

@ -89,7 +89,6 @@ reassign(const ThreadSafePointerToBase<To> &copy) {
reassign((To *)copy._void_ptr);
}
#ifdef DO_MEMORY_USAGE
/**
* Ensures that the MemoryUsage record for the pointer has the right type of
* object, if we know the type ourselves.
@ -97,6 +96,7 @@ reassign(const ThreadSafePointerToBase<To> &copy) {
template<class T>
void ThreadSafePointerToBase<T>::
update_type(To *ptr) {
#ifdef DO_MEMORY_USAGE
TypeHandle type = get_type_handle(To);
if (type == TypeHandle::none()) {
do_init_type(To);
@ -105,9 +105,8 @@ update_type(To *ptr) {
if (type != TypeHandle::none()) {
MemoryUsage::update_type(ptr, type);
}
}
#endif // DO_MEMORY_USAGE
}
/**
* A convenient way to set the ThreadSafePointerTo object to NULL. (Assignment

View File

@ -40,9 +40,7 @@ protected:
INLINE void reassign(To *ptr);
INLINE void reassign(const ThreadSafePointerToBase<To> &copy);
#ifdef DO_MEMORY_USAGE
void update_type(To *ptr);
#endif // DO_MEMORY_USAGE
// No assignment or retrieval functions are declared in
// ThreadSafePointerToBase, because we will have to specialize on const vs.

View File

@ -178,11 +178,9 @@ private:
static TypeHandle _texcoord_type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<InternalName>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const InternalName &tcn);

View File

@ -83,11 +83,9 @@ private:
static TypeHandle _type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<GeometricBoundingVolume>::update_type(To *ptr) {}
#endif
#include "geometricBoundingVolume.I"

View File

@ -74,11 +74,9 @@ private:
Occluders _occluders;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<CullPlanes>::update_type(To *ptr) {}
#endif
#include "cullPlanes.I"

View File

@ -17,7 +17,7 @@
INLINE CullableObject::
CullableObject() {
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
MemoryUsage::record_pointer(this, get_class_type());
#endif
}
@ -33,7 +33,7 @@ CullableObject(CPT(Geom) geom, CPT(RenderState) state,
_internal_transform(move(internal_transform))
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
MemoryUsage::record_pointer(this, get_class_type());
#endif
}
@ -48,7 +48,7 @@ CullableObject(const CullableObject &copy) :
_internal_transform(copy._internal_transform)
{
#ifdef DO_MEMORY_USAGE
MemoryUsage::update_type(this, get_class_type());
MemoryUsage::record_pointer(this, get_class_type());
#endif
}

View File

@ -21,7 +21,6 @@
#include "renderState.h"
#include "transformState.h"
#include "pointerTo.h"
#include "referenceCount.h"
#include "geomNode.h"
#include "cullTraverserData.h"
#include "pStatCollector.h"
@ -39,11 +38,7 @@ class GeomMunger;
* The smallest atom of cull. This is normally just a Geom and its associated
* state, but it also contain a draw callback.
*/
class EXPCL_PANDA_PGRAPH CullableObject
#ifdef DO_MEMORY_USAGE
: public ReferenceCount // We inherit from ReferenceCount just to get the memory type tracking that MemoryUsage provides.
#endif // DO_MEMORY_USAGE
{
class EXPCL_PANDA_PGRAPH CullableObject {
public:
INLINE CullableObject();
INLINE CullableObject(CPT(Geom) geom, CPT(RenderState) state,
@ -124,13 +119,7 @@ public:
return _type_handle;
}
static void init_type() {
#ifdef DO_MEMORY_USAGE
ReferenceCount::init_type();
register_type(_type_handle, "CullableObject",
ReferenceCount::get_class_type());
#else
register_type(_type_handle, "CullableObject");
#endif // DO_MEMORY_USAGE
}
private:

View File

@ -125,11 +125,9 @@ private:
friend class NodePath;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<NodePathComponent>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const NodePathComponent &comp);

View File

@ -907,11 +907,9 @@ private:
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<PandaNode>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const PandaNode &node) {
node.output(out);

View File

@ -368,11 +368,9 @@ private:
friend class Extension<RenderState>;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<RenderState>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const RenderState &state) {
state.output(out);

View File

@ -406,11 +406,9 @@ private:
friend class Extension<TransformState>;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<TransformState>::update_type(To *ptr) {}
#endif
INLINE ostream &operator << (ostream &out, const TransformState &state) {
state.output(out);

View File

@ -161,11 +161,9 @@ private:
static TypeHandle _type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<CopyOnWriteObject>::update_type(To *ptr) {}
#endif
#include "copyOnWriteObject.I"

View File

@ -61,10 +61,9 @@ private:
static TypeHandle _type_handle;
};
#ifdef DO_MEMORY_USAGE
// We can safely redefine this as a no-op.
template<>
INLINE void PointerToBase<TypedWritableReferenceCount>::update_type(To *ptr) {}
#endif
#include "typedWritableReferenceCount.I"