Panda3D
Loading...
Searching...
No Matches
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 */
24MemoryInfo::
25MemoryInfo() {
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 */
39TypeHandle MemoryInfo::
40get_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 */
76void MemoryInfo::
77determine_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 */
124bool MemoryInfo::
125update_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
This is a convenience class to specialize ConfigVariable as a boolean type.
get_value
Returns the variable's value.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
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
A base class for things which need to inherit from both TypedObject and from ReferenceCount.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.