Panda3D
Loading...
Searching...
No Matches
deletedChain.h
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 deletedChain.h
10 * @author drose
11 * @date 2006-04-01
12 */
13
14#ifndef DELETEDCHAIN_H
15#define DELETEDCHAIN_H
16
17#include "dtoolbase.h"
18#include "deletedBufferChain.h"
19#include <assert.h>
20
21/**
22 * This template class can be used to provide faster allocation/deallocation
23 * for many Panda objects. It works by maintaining a linked list of deleted
24 * objects that are all of the same type; when a new object is allocated that
25 * matches that type, the same space is just reused.
26 *
27 * This class is actually a layer on top of DeletedBufferChain, which handles
28 * the actual allocation. This class just provides the typecasting.
29 *
30 * Of course, this trick of maintaining the deleted object chain won't work in
31 * the presence of polymorphism, where you might have many classes that derive
32 * from a base class, and all of them have a different size--unless you
33 * instantiate a DeletedChain for *every* kind of derived class. The
34 * ALLOC_DELETED_CHAIN macro, below, is designed to make this easy.
35 */
36template<class Type>
38public:
39 INLINE Type *allocate(size_t size, TypeHandle type_handle);
40 INLINE void deallocate(Type *ptr, TypeHandle type_handle);
41
42 INLINE bool validate(const Type *ptr);
43
44 static INLINE ReferenceCount *make_ref_ptr(void *ptr);
45 static INLINE ReferenceCount *make_ref_ptr(ReferenceCount *ptr);
46
47private:
48 INLINE void init_deleted_chain();
49
50 DeletedBufferChain *_chain;
51};
52
53/**
54 * This template class is used to conveniently declare a single instance of
55 * the DeletedChain template object, above, for a particular type.
56 *
57 * It relies on the fact that the compiler and linker should unify all
58 * references to this static pointer for a given type, as per the C++ spec.
59 * However, this sometimes fails; and if the compiler fails to do this, it
60 * mostly won't be a big deal; it just means there will be multiple unrelated
61 * chains of deleted objects for a particular type. This is only a problem if
62 * the code structure causes objects to be allocated from one chain and freed
63 * to another, which can lead to leaks.
64 */
65template<class Type>
67public:
68 INLINE static Type *allocate(size_t size, TypeHandle type_handle);
69 INLINE static void deallocate(Type *ptr, TypeHandle type_handle);
70
71 INLINE static bool validate(const Type *ptr);
72
73 static DeletedChain<Type> _chain;
74};
75
76#ifdef USE_DELETED_CHAIN
77// Place this macro within a class definition to define appropriate operator
78// new and delete methods that take advantage of DeletedChain.
79#define ALLOC_DELETED_CHAIN(Type) \
80 inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
81 return (void *)StaticDeletedChain< Type >::allocate(size, get_type_handle(Type)); \
82 } \
83 inline void *operator new(size_t size, void *ptr) { \
84 (void) size; \
85 return ptr; \
86 } \
87 inline void operator delete(void *ptr) { \
88 if (ptr != nullptr) { \
89 StaticDeletedChain< Type >::deallocate((Type *)ptr, get_type_handle(Type)); \
90 } \
91 } \
92 inline void operator delete(void *, void *) { \
93 } \
94 inline static bool validate_ptr(const void *ptr) { \
95 return StaticDeletedChain< Type >::validate((const Type *)ptr); \
96 }
97
98// Use this variant of the above macro in cases in which the compiler fails to
99// unify the static template pointers properly, to prevent leaks.
100#define ALLOC_DELETED_CHAIN_DECL(Type) \
101 inline void *operator new(size_t size) RETURNS_ALIGNED(MEMORY_HOOK_ALIGNMENT) { \
102 return (void *)_deleted_chain.allocate(size, get_type_handle(Type)); \
103 } \
104 inline void *operator new(size_t size, void *ptr) { \
105 (void) size; \
106 return ptr; \
107 } \
108 inline void operator delete(void *ptr) { \
109 if (ptr != nullptr) { \
110 _deleted_chain.deallocate((Type *)ptr, get_type_handle(Type)); \
111 } \
112 } \
113 inline void operator delete(void *, void *) { \
114 } \
115 inline static bool validate_ptr(const void *ptr) { \
116 return _deleted_chain.validate((const Type *)ptr); \
117 } \
118 static DeletedChain< Type > _deleted_chain;
119
120// When you use ALLOC_DELETED_CHAIN_DECL in a class body, you must also put
121// this line in the .cxx file defining that class body.
122#define ALLOC_DELETED_CHAIN_DEF(Type) \
123 DeletedChain< Type > Type::_deleted_chain;
124
125#else // USE_DELETED_CHAIN
126
127#define ALLOC_DELETED_CHAIN(Type) \
128 inline static bool validate_ptr(const void *ptr) { \
129 return (ptr != nullptr); \
130 }
131#define ALLOC_DELETED_CHAIN_DECL(Type) \
132 inline static bool validate_ptr(const void *ptr) { \
133 return (ptr != nullptr); \
134 }
135#define ALLOC_DELETED_CHAIN_DEF(Type)
136
137#endif // USE_DELETED_CHAIN
138
139#include "deletedChain.T"
140
141#endif
This template class can be used to provide faster allocation/deallocation for many Panda objects.
This template class can be used to provide faster allocation/deallocation for many Panda objects.
A base class for all things that want to be reference-counted.
This template class is used to conveniently declare a single instance of the DeletedChain template ob...
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.