Panda3D

memoryInfo.cxx
Go to the documentation of this file.
1 /**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file memoryInfo.cxx
10 * @author drose
11 * @date 2001-06-04
12 */
13
14 #include "memoryInfo.h"
15
16 #ifdef DO_MEMORY_USAGE
17
18 #include "typedReferenceCount.h"
19 #include "typeHandle.h"
20
21 /**
22 *
23 */
24 MemoryInfo::
25 MemoryInfo() {
26 _void_ptr = nullptr;
27 _ref_ptr = nullptr;
28 _typed_ptr = nullptr;
29 _size = 0;
30 _static_type = TypeHandle::none();
31 _dynamic_type = TypeHandle::none();
32
33 _flags = 0;
34 }
35
36 /**
37 * Returns the best known type, dynamic or static, of the pointer.
38 */
39 TypeHandle MemoryInfo::
40 get_type() {
41 // If we don't want to consider the dynamic type any further, use what we've
42 // got.
43 if ((_flags & F_reconsider_dynamic_type) == 0) {
44 if (_dynamic_type == TypeHandle::none()) {
45 return _static_type;
46 }
47 return _dynamic_type;
48 }
49
50 // Otherwise, examine the pointer again and make sure it's still the best
51 // information we have. We have to do this each time because if we happen
52 // to be examining the pointer from within the constructor or destructor,
53 // its dynamic type will appear to be less-specific than it actually is, so
54 // our idea of what type this thing is could change from time to time.
55 determine_dynamic_type();
56
57 // Now return the more specific of the two.
58 TypeHandle type = _static_type;
59 update_type_handle(type, _dynamic_type);
60
61 if (type != _static_type) {
62 if (express_cat.is_spam()) {
63 express_cat.spam()
64 << "Pointer " << get_void_ptr() << " has static type "
65 << _static_type << " and dynamic type " << _dynamic_type << "\n";
66 }
67 }
68
69 return type;
70 }
71
72 /**
73 * Tries to determine the actual type of the object to which this thing is
74 * pointed, if possible.
75 */
76 void MemoryInfo::
77 determine_dynamic_type() {
78 if ((_flags & F_reconsider_dynamic_type) != 0 &&
79 _static_type != TypeHandle::none()) {
80 // See if we know enough now to infer the dynamic type from the pointer.
81
82 if (_typed_ptr == nullptr) {
83 // If our static type is known to inherit from TypedReferenceCount, then
84 // we can directly downcast to get the TypedObject pointer.
85 if (_static_type.is_derived_from(TypedReferenceCount::get_class_type())) {
86 _typed_ptr = (TypedReferenceCount *)_ref_ptr;
87 }
88 }
89
90 if (_typed_ptr != nullptr) {
91 // If we have a TypedObject pointer, we can determine the type. This
92 // might still not return the exact type, particularly if we are being
93 // called within the destructor or constructor of this object.
94 TypeHandle got_type = _typed_ptr->get_type();
95
96 if (got_type == TypeHandle::none()) {
97 express_cat.warning()
98 << "Found an unregistered type in a " << _static_type
99 << " pointer:\n"
100 << "Check derived types of " << _static_type
101 << " and make sure that all are being initialized.\n";
102 _dynamic_type = _static_type;
103 _flags &= ~F_reconsider_dynamic_type;
104
105 if (ConfigVariableBool("raise-unregistered-type", false).get_value()) {
106 nassert_raise("Unregistered type");
107 }
108 return;
109 }
110
111 //TypeHandle orig_type = _dynamic_type;
112 update_type_handle(_dynamic_type, got_type);
113 }
114 }
115 }
116
117
118 /**
119 * Updates the given destination TypeHandle with the refined TypeHandle, if it
120 * is in fact more specific than the original value for the destination.
121 * Returns true if the update was trouble-free, or false if the two types were
122 * not apparently related.
123 */
124 bool MemoryInfo::
125 update_type_handle(TypeHandle &destination, TypeHandle refined) {
126 if (refined == TypeHandle::none()) {
127 express_cat.error()
128 << "Attempt to update type of " << get_void_ptr()
129 << "(type is " << get_type()
130 << ") to an undefined type!\n";
131
132 } else if (destination == refined) {
133 // Updating with the same type, no problem.
134
135 } else if (destination.is_derived_from(refined)) {
136 // Updating with a less-specific type, no problem.
137
138 } else if (destination == TypeHandle::none() ||
139 refined.is_derived_from(destination)) {
140 // Updating with a more-specific type, no problem.
141 if (express_cat.is_spam()) {
142 express_cat.spam()
143 << "Updating " << get_void_ptr() << " from type "
144 << destination << " to type " << refined << "\n";
145 }
146 destination = refined;
147
148 } else {
149 // Unrelated types, which might or might not be a problem.
150 express_cat.warning()
151 << "Pointer " << get_void_ptr() << " previously indicated as type "
152 << destination << " is now type " << refined << "!\n";
153 return false;
154 }
155
156 return true;
157 }
158
159 #endif // DO_MEMORY_USAGE
ConfigVariableBool
This is a convenience class to specialize ConfigVariable as a boolean type.
Definition: configVariableBool.h:23
ConfigVariableBool::get_value
get_value
Returns the variable's value.
Definition: configVariableBool.h:40
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
TypeHandle::is_derived_from
bool is_derived_from(TypeHandle parent, TypedObject *object=nullptr) const
Returns true if this type is derived from the indicated type, false otherwise.
Definition: typeHandle.I:105
TypedReferenceCount
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
Definition: typedReferenceCount.h:31
memoryInfo.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
typeHandle.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
typedReferenceCount.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.