Panda3D

memoryInfo.cxx

00001 // Filename: memoryInfo.cxx
00002 // Created by:  drose (04Jun01)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "memoryInfo.h"
00016 
00017 #ifdef DO_MEMORY_USAGE
00018 
00019 #include "typedReferenceCount.h"
00020 #include "typeHandle.h"
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: MemoryInfo::Constructor
00024 //       Access: Public
00025 //  Description: 
00026 ////////////////////////////////////////////////////////////////////
00027 MemoryInfo::
00028 MemoryInfo() {
00029   _void_ptr = (void *)NULL;
00030   _ref_ptr = (ReferenceCount *)NULL;
00031   _typed_ptr = (TypedObject *)NULL;
00032   _size = 0;
00033   _static_type = TypeHandle::none();
00034   _dynamic_type = TypeHandle::none();
00035 
00036   _flags = 0;
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: MemoryInfo::get_type
00041 //       Access: Public
00042 //  Description: Returns the best known type, dynamic or static, of
00043 //               the pointer.
00044 ////////////////////////////////////////////////////////////////////
00045 TypeHandle MemoryInfo::
00046 get_type() {
00047   // If we don't want to consider the dynamic type any further, use
00048   // what we've got.
00049   if ((_flags & F_reconsider_dynamic_type) == 0) {
00050     if (_dynamic_type == TypeHandle::none()) {
00051       return _static_type;
00052     }
00053     return _dynamic_type;
00054   }
00055 
00056   // Otherwise, examine the pointer again and make sure it's still the
00057   // best information we have.  We have to do this each time because
00058   // if we happen to be examining the pointer from within the
00059   // constructor or destructor, its dynamic type will appear to be
00060   // less-specific than it actually is, so our idea of what type this
00061   // thing is could change from time to time.
00062   determine_dynamic_type();
00063 
00064   // Now return the more specific of the two.
00065   TypeHandle type = _static_type;
00066   update_type_handle(type, _dynamic_type);
00067 
00068   if (type != _static_type) {
00069     if (express_cat.is_spam()) {
00070       express_cat.spam()
00071         << "Pointer " << get_void_ptr() << " has static type "
00072         << _static_type << " and dynamic type " << _dynamic_type << "\n";
00073     }
00074   }
00075 
00076   return type;
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: MemoryInfo::determine_dynamic_type
00081 //       Access: Private
00082 //  Description: Tries to determine the actual type of the object to
00083 //               which this thing is pointed, if possible.
00084 ////////////////////////////////////////////////////////////////////
00085 void MemoryInfo::
00086 determine_dynamic_type() {
00087   if ((_flags & F_reconsider_dynamic_type) != 0 &&
00088       _static_type != TypeHandle::none()) {
00089     // See if we know enough now to infer the dynamic type from the
00090     // pointer.
00091 
00092     if (_typed_ptr == (TypedObject *)NULL) {
00093       // If our static type is known to inherit from
00094       // TypedReferenceCount, then we can directly downcast to get the
00095       // TypedObject pointer.
00096       if (_static_type.is_derived_from(TypedReferenceCount::get_class_type())) {
00097         _typed_ptr = (TypedReferenceCount *)_ref_ptr;
00098       }
00099     }
00100 
00101     if (_typed_ptr != (TypedObject *)NULL) {
00102       // If we have a TypedObject pointer, we can determine the type.
00103       // This might still not return the exact type, particularly if
00104       // we are being called within the destructor or constructor of
00105       // this object.
00106       TypeHandle got_type = _typed_ptr->get_type();
00107 
00108       if (got_type == TypeHandle::none()) {
00109         express_cat.warning()
00110           << "Found an unregistered type in a " << _static_type
00111           << " pointer:\n"
00112           << "Check derived types of " << _static_type
00113           << " and make sure that all are being initialized.\n";
00114         _dynamic_type = _static_type;
00115         _flags &= ~F_reconsider_dynamic_type;
00116 
00117         //nassert_raise("Unregistered type");
00118         return;
00119       }
00120 
00121       TypeHandle orig_type = _dynamic_type;
00122       if (update_type_handle(_dynamic_type, got_type)) {
00123         if (orig_type != _dynamic_type) {
00124           if (express_cat.is_spam()) {
00125             express_cat.spam()
00126               << "Updating " << get_void_ptr() << " from type "
00127               << orig_type << " to type " << _dynamic_type << "\n";
00128           }
00129         }
00130 
00131       } else {
00132         express_cat.warning()
00133           << "Pointer " << get_void_ptr() << " previously indicated as type "
00134           << orig_type << " is now type " << got_type << "!\n";
00135       }
00136     }    
00137   }
00138 }
00139 
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: MemoryInfo::update_type_handle
00143 //       Access: Private
00144 //  Description: Updates the given destination TypeHandle with the
00145 //               refined TypeHandle, if it is in fact more specific
00146 //               than the original value for the destination.  Returns
00147 //               true if the update was trouble-free, or false if the
00148 //               two types were not apparently related.
00149 ////////////////////////////////////////////////////////////////////
00150 bool MemoryInfo::
00151 update_type_handle(TypeHandle &destination, TypeHandle refined) {
00152   if (refined == TypeHandle::none()) {
00153     express_cat.error()
00154       << "Attempt to update type of " << get_void_ptr()
00155       << "(type is " << get_type()
00156       << ") to an undefined type!\n";
00157 
00158   } else if (destination == refined) {
00159     // Updating with the same type, no problem.
00160 
00161   } else if (destination.is_derived_from(refined)) {
00162     // Updating with a less-specific type, no problem.
00163 
00164   } else if (refined.is_derived_from(destination)) {
00165     // Updating with a more-specific type, no problem.
00166     destination = refined;
00167 
00168   } else {
00169     // Unrelated types, which might or might not be a problem.
00170     return false;
00171   }
00172   
00173   return true;
00174 }
00175 
00176 #endif  // DO_MEMORY_USAGE
 All Classes Functions Variables Enumerations