mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 00:06:44 -04:00
dtoolbase: Make MemoryHook constant-initialized
init_memory_hook() is no longer required, eliminating static initialization order issues This required moving the DeletedBufferChain map elsewhere, which now also has a const-initialized array for relatively small allocations. Also, deletedChain.T has been renamed to deletedChain.I Fixes #539
This commit is contained in:
parent
6f9897fe49
commit
bf65624298
@ -21,7 +21,7 @@ set(P3DTOOLBASE_HEADERS
|
|||||||
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I
|
atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I
|
||||||
cmath.I cmath.h
|
cmath.I cmath.h
|
||||||
deletedBufferChain.h deletedBufferChain.I
|
deletedBufferChain.h deletedBufferChain.I
|
||||||
deletedChain.h deletedChain.T
|
deletedChain.h deletedChain.I
|
||||||
dtoolbase.h dtoolbase_cc.h dtoolsymbols.h
|
dtoolbase.h dtoolbase_cc.h dtoolsymbols.h
|
||||||
dtool_platform.h
|
dtool_platform.h
|
||||||
fakestringstream.h
|
fakestringstream.h
|
||||||
|
@ -11,6 +11,34 @@
|
|||||||
* @date 2007-07-20
|
* @date 2007-07-20
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use get_deleted_chain() to get a new DeletedBufferChain of the appropriate
|
||||||
|
* size.
|
||||||
|
*/
|
||||||
|
constexpr DeletedBufferChain::
|
||||||
|
DeletedBufferChain(size_t buffer_size) : _buffer_size(buffer_size) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
INLINE DeletedBufferChain::
|
||||||
|
DeletedBufferChain(DeletedBufferChain &&from) noexcept :
|
||||||
|
_deleted_chain(from._deleted_chain),
|
||||||
|
_buffer_size(from._buffer_size) {
|
||||||
|
from._deleted_chain = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
*/
|
||||||
|
INLINE DeletedBufferChain::
|
||||||
|
DeletedBufferChain(const DeletedBufferChain ©) :
|
||||||
|
_deleted_chain(nullptr),
|
||||||
|
_buffer_size(copy._buffer_size) {
|
||||||
|
assert(copy._deleted_chain == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the pointer is valid, false if it has been deleted or if it
|
* Returns true if the pointer is valid, false if it has been deleted or if it
|
||||||
* was never a valid pointer.
|
* was never a valid pointer.
|
||||||
@ -41,6 +69,30 @@ get_buffer_size() const {
|
|||||||
return _buffer_size;
|
return _buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
INLINE bool DeletedBufferChain::
|
||||||
|
operator < (const DeletedBufferChain &other) const {
|
||||||
|
return _buffer_size < other._buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a deleted chain of the given size.
|
||||||
|
*/
|
||||||
|
INLINE DeletedBufferChain *DeletedBufferChain::
|
||||||
|
get_deleted_chain(size_t buffer_size) {
|
||||||
|
// We must allocate at least this much space for bookkeeping reasons.
|
||||||
|
buffer_size = (std::max)(buffer_size, sizeof(ObjectNode));
|
||||||
|
|
||||||
|
size_t index = ((buffer_size + sizeof(void *) - 1) / sizeof(void *)) - 1;
|
||||||
|
if (index < num_small_deleted_chains) {
|
||||||
|
return &_small_deleted_chains[index];
|
||||||
|
} else {
|
||||||
|
return get_large_deleted_chain((index + 1) * sizeof(void *));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Casts an ObjectNode* to a void* buffer.
|
* Casts an ObjectNode* to a void* buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -14,18 +14,34 @@
|
|||||||
#include "deletedBufferChain.h"
|
#include "deletedBufferChain.h"
|
||||||
#include "memoryHook.h"
|
#include "memoryHook.h"
|
||||||
|
|
||||||
/**
|
#include <set>
|
||||||
* Use the global MemoryHook to get a new DeletedBufferChain of the
|
|
||||||
* appropriate size.
|
|
||||||
*/
|
|
||||||
DeletedBufferChain::
|
|
||||||
DeletedBufferChain(size_t buffer_size) {
|
|
||||||
_deleted_chain = nullptr;
|
|
||||||
_buffer_size = buffer_size;
|
|
||||||
|
|
||||||
// We must allocate at least this much space for bookkeeping reasons.
|
DeletedBufferChain DeletedBufferChain::_small_deleted_chains[DeletedBufferChain::num_small_deleted_chains] = {
|
||||||
_buffer_size = std::max(_buffer_size, sizeof(ObjectNode));
|
DeletedBufferChain(sizeof(void *)),
|
||||||
}
|
DeletedBufferChain(sizeof(void *) * 2),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 3),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 4),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 5),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 6),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 7),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 8),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 9),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 10),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 11),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 12),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 13),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 14),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 15),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 16),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 17),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 18),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 19),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 20),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 21),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 22),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 23),
|
||||||
|
DeletedBufferChain(sizeof(void *) * 24),
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates the memory for a new buffer of the indicated size (which must be
|
* Allocates the memory for a new buffer of the indicated size (which must be
|
||||||
@ -139,3 +155,16 @@ deallocate(void *ptr, TypeHandle type_handle) {
|
|||||||
PANDA_FREE_SINGLE(ptr);
|
PANDA_FREE_SINGLE(ptr);
|
||||||
#endif // USE_DELETED_CHAIN
|
#endif // USE_DELETED_CHAIN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new DeletedBufferChain.
|
||||||
|
*/
|
||||||
|
DeletedBufferChain *DeletedBufferChain::
|
||||||
|
get_large_deleted_chain(size_t buffer_size) {
|
||||||
|
static MutexImpl lock;
|
||||||
|
lock.lock();
|
||||||
|
static std::set<DeletedBufferChain> deleted_chains;
|
||||||
|
DeletedBufferChain *result = (DeletedBufferChain *)&*deleted_chains.insert(DeletedBufferChain(buffer_size)).first;
|
||||||
|
lock.unlock();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -58,16 +58,25 @@ enum DeletedChainFlag : unsigned int {
|
|||||||
*/
|
*/
|
||||||
class EXPCL_DTOOL_DTOOLBASE DeletedBufferChain {
|
class EXPCL_DTOOL_DTOOLBASE DeletedBufferChain {
|
||||||
protected:
|
protected:
|
||||||
DeletedBufferChain(size_t buffer_size);
|
constexpr explicit DeletedBufferChain(size_t buffer_size);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
INLINE DeletedBufferChain(DeletedBufferChain &&from) noexcept;
|
||||||
|
INLINE DeletedBufferChain(const DeletedBufferChain ©);
|
||||||
|
|
||||||
void *allocate(size_t size, TypeHandle type_handle);
|
void *allocate(size_t size, TypeHandle type_handle);
|
||||||
void deallocate(void *ptr, TypeHandle type_handle);
|
void deallocate(void *ptr, TypeHandle type_handle);
|
||||||
|
|
||||||
INLINE bool validate(void *ptr);
|
INLINE bool validate(void *ptr);
|
||||||
INLINE size_t get_buffer_size() const;
|
INLINE size_t get_buffer_size() const;
|
||||||
|
|
||||||
|
INLINE bool operator < (const DeletedBufferChain &other) const;
|
||||||
|
|
||||||
|
static INLINE DeletedBufferChain *get_deleted_chain(size_t buffer_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static DeletedBufferChain *get_large_deleted_chain(size_t buffer_size);
|
||||||
|
|
||||||
class ObjectNode {
|
class ObjectNode {
|
||||||
public:
|
public:
|
||||||
#ifdef USE_DELETEDCHAINFLAG
|
#ifdef USE_DELETEDCHAINFLAG
|
||||||
@ -87,10 +96,10 @@ private:
|
|||||||
static INLINE void *node_to_buffer(ObjectNode *node);
|
static INLINE void *node_to_buffer(ObjectNode *node);
|
||||||
static INLINE ObjectNode *buffer_to_node(void *buffer);
|
static INLINE ObjectNode *buffer_to_node(void *buffer);
|
||||||
|
|
||||||
ObjectNode *_deleted_chain;
|
ObjectNode *_deleted_chain = nullptr;
|
||||||
|
|
||||||
MutexImpl _lock;
|
MutexImpl _lock;
|
||||||
size_t _buffer_size;
|
const size_t _buffer_size;
|
||||||
|
|
||||||
#ifndef USE_DELETEDCHAINFLAG
|
#ifndef USE_DELETEDCHAINFLAG
|
||||||
// Without DELETEDCHAINFLAG, we don't even store the _flag member at all.
|
// Without DELETEDCHAINFLAG, we don't even store the _flag member at all.
|
||||||
@ -101,6 +110,11 @@ private:
|
|||||||
static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer);
|
static const size_t flag_reserved_bytes = sizeof(AtomicAdjust::Integer);
|
||||||
#endif // USE_DELETEDCHAINFLAG
|
#endif // USE_DELETEDCHAINFLAG
|
||||||
|
|
||||||
|
// This array stores the deleted chains for smaller sizes, starting with
|
||||||
|
// sizeof(void *) and increasing in multiples thereof.
|
||||||
|
static const size_t num_small_deleted_chains = 24;
|
||||||
|
static DeletedBufferChain _small_deleted_chains[num_small_deleted_chains];
|
||||||
|
|
||||||
friend class MemoryHook;
|
friend class MemoryHook;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* license. You should have received a copy of this license along
|
* license. You should have received a copy of this license along
|
||||||
* with this source code in a file named "LICENSE."
|
* with this source code in a file named "LICENSE."
|
||||||
*
|
*
|
||||||
* @file deletedChain.T
|
* @file deletedChain.I
|
||||||
* @author drose
|
* @author drose
|
||||||
* @date 2006-04-01
|
* @date 2006-04-01
|
||||||
*/
|
*/
|
||||||
@ -82,7 +82,7 @@ validate(const Type *ptr) {
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
INLINE ReferenceCount *DeletedChain<Type>::
|
INLINE ReferenceCount *DeletedChain<Type>::
|
||||||
make_ref_ptr(void *) {
|
make_ref_ptr(void *) {
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,9 +106,8 @@ make_ref_ptr(ReferenceCount *ptr) {
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void DeletedChain<Type>::
|
void DeletedChain<Type>::
|
||||||
init_deleted_chain() {
|
init_deleted_chain() {
|
||||||
if (_chain == (DeletedBufferChain *)NULL) {
|
if (_chain == nullptr) {
|
||||||
init_memory_hook();
|
_chain = DeletedBufferChain::get_deleted_chain(sizeof(Type));
|
||||||
_chain = memory_hook->get_deleted_chain(sizeof(Type));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +136,6 @@ public:
|
|||||||
|
|
||||||
#endif // USE_DELETED_CHAIN
|
#endif // USE_DELETED_CHAIN
|
||||||
|
|
||||||
#include "deletedChain.T"
|
#include "deletedChain.I"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,34 +23,18 @@
|
|||||||
bool __tau_shutdown = false;
|
bool __tau_shutdown = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MemoryHook *memory_hook;
|
MemoryHook default_memory_hook;
|
||||||
|
MemoryHook *memory_hook = &default_memory_hook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any code that might need to use PANDA_MALLOC or PANDA_FREE, or any methods
|
* It used to be necessary to call this before using operator new at static
|
||||||
* of the global memory_hook object, at static init time, should ensure that
|
* init time. There is no need to call this function anymore.
|
||||||
* it calls init_memory_hook() first to ensure that the pointer has been
|
|
||||||
* properly initialized. There is no harm in calling this function more than
|
|
||||||
* once.
|
|
||||||
*
|
|
||||||
* There is no need to call this function other than at static init time.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
init_memory_hook() {
|
init_memory_hook() {
|
||||||
if (memory_hook == nullptr) {
|
assert(memory_hook != nullptr);
|
||||||
memory_hook = new MemoryHook;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here's a quick way to ensure the above function is called at least once at
|
|
||||||
// static init time.
|
|
||||||
class InitMemoryHook {
|
|
||||||
public:
|
|
||||||
InitMemoryHook() {
|
|
||||||
init_memory_hook();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static InitMemoryHook _imh_object;
|
|
||||||
|
|
||||||
#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
|
#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -40,6 +40,9 @@ dec_heap(size_t size) {
|
|||||||
*/
|
*/
|
||||||
INLINE size_t MemoryHook::
|
INLINE size_t MemoryHook::
|
||||||
get_page_size() const {
|
get_page_size() const {
|
||||||
|
if (_page_size == 0) {
|
||||||
|
determine_page_size();
|
||||||
|
}
|
||||||
return _page_size;
|
return _page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +52,9 @@ get_page_size() const {
|
|||||||
*/
|
*/
|
||||||
INLINE size_t MemoryHook::
|
INLINE size_t MemoryHook::
|
||||||
round_up_to_page_size(size_t size) const {
|
round_up_to_page_size(size_t size) const {
|
||||||
|
if (_page_size == 0) {
|
||||||
|
determine_page_size();
|
||||||
|
}
|
||||||
return ((size + _page_size - 1) / _page_size) * _page_size;
|
return ((size + _page_size - 1) / _page_size) * _page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,33 +198,6 @@ ptr_to_alloc(void *ptr, size_t &size) {
|
|||||||
#endif // DO_MEMORY_USAGE
|
#endif // DO_MEMORY_USAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MemoryHook::
|
|
||||||
MemoryHook() {
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
// Windows case.
|
|
||||||
SYSTEM_INFO sysinfo;
|
|
||||||
GetSystemInfo(&sysinfo);
|
|
||||||
|
|
||||||
_page_size = (size_t)sysinfo.dwPageSize;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Posix case.
|
|
||||||
_page_size = sysconf(_SC_PAGESIZE);
|
|
||||||
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
_total_heap_single_size = 0;
|
|
||||||
_total_heap_array_size = 0;
|
|
||||||
_requested_heap_size = 0;
|
|
||||||
_total_mmap_size = 0;
|
|
||||||
_max_heap_size = ~(size_t)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -236,20 +209,8 @@ MemoryHook(const MemoryHook ©) :
|
|||||||
_total_mmap_size(copy._total_mmap_size),
|
_total_mmap_size(copy._total_mmap_size),
|
||||||
_max_heap_size(copy._max_heap_size),
|
_max_heap_size(copy._max_heap_size),
|
||||||
_page_size(copy._page_size) {
|
_page_size(copy._page_size) {
|
||||||
|
|
||||||
copy._lock.lock();
|
|
||||||
_deleted_chains = copy._deleted_chains;
|
|
||||||
copy._lock.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
MemoryHook::
|
|
||||||
~MemoryHook() {
|
|
||||||
// Really, we only have this destructor to shut up gcc about the virtual
|
|
||||||
// functions warning.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates a block of memory from the heap, similar to malloc(). This will
|
* Allocates a block of memory from the heap, similar to malloc(). This will
|
||||||
@ -522,6 +483,9 @@ heap_trim(size_t pad) {
|
|||||||
*/
|
*/
|
||||||
void *MemoryHook::
|
void *MemoryHook::
|
||||||
mmap_alloc(size_t size, bool allow_exec) {
|
mmap_alloc(size_t size, bool allow_exec) {
|
||||||
|
if (_page_size == 0) {
|
||||||
|
determine_page_size();
|
||||||
|
}
|
||||||
assert((size % _page_size) == 0);
|
assert((size % _page_size) == 0);
|
||||||
|
|
||||||
#ifdef DO_MEMORY_USAGE
|
#ifdef DO_MEMORY_USAGE
|
||||||
@ -576,6 +540,7 @@ mmap_alloc(size_t size, bool allow_exec) {
|
|||||||
*/
|
*/
|
||||||
void MemoryHook::
|
void MemoryHook::
|
||||||
mmap_free(void *ptr, size_t size) {
|
mmap_free(void *ptr, size_t size) {
|
||||||
|
assert(_page_size != 0);
|
||||||
assert((size % _page_size) == 0);
|
assert((size % _page_size) == 0);
|
||||||
|
|
||||||
#ifdef DO_MEMORY_USAGE
|
#ifdef DO_MEMORY_USAGE
|
||||||
@ -601,29 +566,6 @@ void MemoryHook::
|
|||||||
mark_pointer(void *, size_t, ReferenceCount *) {
|
mark_pointer(void *, size_t, ReferenceCount *) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a pointer to a global DeletedBufferChain object suitable for
|
|
||||||
* allocating arrays of the indicated size. There is one unique
|
|
||||||
* DeletedBufferChain object for every different size.
|
|
||||||
*/
|
|
||||||
DeletedBufferChain *MemoryHook::
|
|
||||||
get_deleted_chain(size_t buffer_size) {
|
|
||||||
DeletedBufferChain *chain;
|
|
||||||
|
|
||||||
_lock.lock();
|
|
||||||
DeletedChains::iterator dci = _deleted_chains.find(buffer_size);
|
|
||||||
if (dci != _deleted_chains.end()) {
|
|
||||||
chain = (*dci).second;
|
|
||||||
} else {
|
|
||||||
// Once allocated, this DeletedBufferChain object is never deleted.
|
|
||||||
chain = new DeletedBufferChain(buffer_size);
|
|
||||||
_deleted_chains.insert(DeletedChains::value_type(buffer_size, chain));
|
|
||||||
}
|
|
||||||
|
|
||||||
_lock.unlock();
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This callback method is called whenever a low-level call to call_malloc()
|
* This callback method is called whenever a low-level call to call_malloc()
|
||||||
* has returned NULL, indicating failure.
|
* has returned NULL, indicating failure.
|
||||||
@ -656,3 +598,24 @@ overflow_heap_size() {
|
|||||||
_max_heap_size = ~(size_t)0;
|
_max_heap_size = ~(size_t)0;
|
||||||
#endif // DO_MEMORY_USAGE
|
#endif // DO_MEMORY_USAGE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the operating system for the page size.
|
||||||
|
*/
|
||||||
|
void MemoryHook::
|
||||||
|
determine_page_size() const {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows case.
|
||||||
|
SYSTEM_INFO sysinfo;
|
||||||
|
GetSystemInfo(&sysinfo);
|
||||||
|
|
||||||
|
_page_size = (size_t)sysinfo.dwPageSize;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Posix case.
|
||||||
|
_page_size = sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
assert(_page_size != 0);
|
||||||
|
}
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
#include "mutexImpl.h"
|
#include "mutexImpl.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class DeletedBufferChain;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides a wrapper around the various possible malloc schemes
|
* This class provides a wrapper around the various possible malloc schemes
|
||||||
* Panda might employ. It also exists to allow the MemoryUsage class in Panda
|
* Panda might employ. It also exists to allow the MemoryUsage class in Panda
|
||||||
@ -36,9 +34,9 @@ class DeletedBufferChain;
|
|||||||
*/
|
*/
|
||||||
class EXPCL_DTOOL_DTOOLBASE MemoryHook {
|
class EXPCL_DTOOL_DTOOLBASE MemoryHook {
|
||||||
public:
|
public:
|
||||||
MemoryHook();
|
constexpr MemoryHook() = default;
|
||||||
MemoryHook(const MemoryHook ©);
|
MemoryHook(const MemoryHook ©);
|
||||||
virtual ~MemoryHook();
|
virtual ~MemoryHook() = default;
|
||||||
|
|
||||||
virtual void *heap_alloc_single(size_t size);
|
virtual void *heap_alloc_single(size_t size);
|
||||||
virtual void heap_free_single(void *ptr);
|
virtual void heap_free_single(void *ptr);
|
||||||
@ -63,29 +61,26 @@ public:
|
|||||||
|
|
||||||
virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr);
|
virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr);
|
||||||
|
|
||||||
DeletedBufferChain *get_deleted_chain(size_t buffer_size);
|
|
||||||
|
|
||||||
virtual void alloc_fail(size_t attempted_size);
|
virtual void alloc_fail(size_t attempted_size);
|
||||||
|
|
||||||
INLINE static size_t get_ptr_size(void *ptr);
|
INLINE static size_t get_ptr_size(void *ptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TVOLATILE AtomicAdjust::Integer _total_heap_single_size;
|
TVOLATILE AtomicAdjust::Integer _total_heap_single_size = 0;
|
||||||
TVOLATILE AtomicAdjust::Integer _total_heap_array_size;
|
TVOLATILE AtomicAdjust::Integer _total_heap_array_size = 0;
|
||||||
TVOLATILE AtomicAdjust::Integer _requested_heap_size;
|
TVOLATILE AtomicAdjust::Integer _requested_heap_size = 0;
|
||||||
TVOLATILE AtomicAdjust::Integer _total_mmap_size;
|
TVOLATILE AtomicAdjust::Integer _total_mmap_size = 0;
|
||||||
|
|
||||||
// If the allocated heap size crosses this threshold, we call
|
// If the allocated heap size crosses this threshold, we call
|
||||||
// overflow_heap_size().
|
// overflow_heap_size().
|
||||||
size_t _max_heap_size;
|
size_t _max_heap_size = ~(size_t)0;
|
||||||
|
|
||||||
virtual void overflow_heap_size();
|
virtual void overflow_heap_size();
|
||||||
|
|
||||||
private:
|
void determine_page_size() const;
|
||||||
size_t _page_size;
|
|
||||||
|
|
||||||
typedef std::map<size_t, DeletedBufferChain *> DeletedChains;
|
private:
|
||||||
DeletedChains _deleted_chains;
|
mutable size_t _page_size = 0;
|
||||||
|
|
||||||
mutable MutexImpl _lock;
|
mutable MutexImpl _lock;
|
||||||
};
|
};
|
||||||
|
@ -539,7 +539,6 @@ TypeRegistry() {
|
|||||||
*/
|
*/
|
||||||
void TypeRegistry::
|
void TypeRegistry::
|
||||||
init_global_pointer() {
|
init_global_pointer() {
|
||||||
init_memory_hook();
|
|
||||||
_global_pointer = new TypeRegistry;
|
_global_pointer = new TypeRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ ConfigVariableManager *ConfigVariableManager::_global_ptr = nullptr;
|
|||||||
*/
|
*/
|
||||||
ConfigVariableManager::
|
ConfigVariableManager::
|
||||||
ConfigVariableManager() {
|
ConfigVariableManager() {
|
||||||
init_memory_hook();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,7 +291,6 @@ write_string(const string &str) {
|
|||||||
Notify *Notify::
|
Notify *Notify::
|
||||||
ptr() {
|
ptr() {
|
||||||
if (_global_ptr == nullptr) {
|
if (_global_ptr == nullptr) {
|
||||||
init_memory_hook();
|
|
||||||
_global_ptr = new Notify;
|
_global_ptr = new Notify;
|
||||||
}
|
}
|
||||||
return _global_ptr;
|
return _global_ptr;
|
||||||
|
@ -649,7 +649,6 @@ void AsyncTaskManager::
|
|||||||
make_global_ptr() {
|
make_global_ptr() {
|
||||||
nassertv(_global_ptr == nullptr);
|
nassertv(_global_ptr == nullptr);
|
||||||
|
|
||||||
init_memory_hook();
|
|
||||||
_global_ptr = new AsyncTaskManager("TaskManager");
|
_global_ptr = new AsyncTaskManager("TaskManager");
|
||||||
_global_ptr->ref();
|
_global_ptr->ref();
|
||||||
}
|
}
|
||||||
|
@ -395,7 +395,6 @@ remove_all_hooks() {
|
|||||||
*/
|
*/
|
||||||
void EventHandler::
|
void EventHandler::
|
||||||
make_global_event_handler() {
|
make_global_event_handler() {
|
||||||
init_memory_hook();
|
|
||||||
_global_event_handler = new EventHandler(EventQueue::get_global_event_queue());
|
_global_event_handler = new EventHandler(EventQueue::get_global_event_queue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,5 @@ dequeue_event() {
|
|||||||
*/
|
*/
|
||||||
void EventQueue::
|
void EventQueue::
|
||||||
make_global_event_queue() {
|
make_global_event_queue() {
|
||||||
init_memory_hook();
|
|
||||||
_global_event_queue = new EventQueue;
|
_global_event_queue = new EventQueue;
|
||||||
}
|
}
|
||||||
|
@ -535,7 +535,6 @@ MemoryUsage(const MemoryHook ©) :
|
|||||||
void MemoryUsage::
|
void MemoryUsage::
|
||||||
init_memory_usage() {
|
init_memory_usage() {
|
||||||
#ifdef DO_MEMORY_USAGE
|
#ifdef DO_MEMORY_USAGE
|
||||||
init_memory_hook();
|
|
||||||
_global_ptr = new MemoryUsage(*memory_hook);
|
_global_ptr = new MemoryUsage(*memory_hook);
|
||||||
memory_hook = _global_ptr;
|
memory_hook = _global_ptr;
|
||||||
#else
|
#else
|
||||||
|
@ -363,7 +363,7 @@ MovieVideoCursor::Buffer::
|
|||||||
Buffer(size_t block_size) :
|
Buffer(size_t block_size) :
|
||||||
_block_size(block_size)
|
_block_size(block_size)
|
||||||
{
|
{
|
||||||
_deleted_chain = memory_hook->get_deleted_chain(_block_size);
|
_deleted_chain = DeletedBufferChain::get_deleted_chain(_block_size);
|
||||||
_block = (unsigned char *)_deleted_chain->allocate(_block_size, get_class_type());
|
_block = (unsigned char *)_deleted_chain->allocate(_block_size, get_class_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,6 @@ init_main_thread() {
|
|||||||
static int count = 0;
|
static int count = 0;
|
||||||
++count;
|
++count;
|
||||||
if (count == 1 && _main_thread == nullptr) {
|
if (count == 1 && _main_thread == nullptr) {
|
||||||
init_memory_hook();
|
|
||||||
_main_thread = new MainThread;
|
_main_thread = new MainThread;
|
||||||
_main_thread->ref();
|
_main_thread->ref();
|
||||||
}
|
}
|
||||||
@ -221,7 +220,6 @@ init_main_thread() {
|
|||||||
void Thread::
|
void Thread::
|
||||||
init_external_thread() {
|
init_external_thread() {
|
||||||
if (_external_thread == nullptr) {
|
if (_external_thread == nullptr) {
|
||||||
init_memory_hook();
|
|
||||||
_external_thread = new ExternalThread;
|
_external_thread = new ExternalThread;
|
||||||
_external_thread->ref();
|
_external_thread->ref();
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ SimpleHashMap(const SimpleHashMap ©) :
|
|||||||
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
||||||
|
|
||||||
init_type();
|
init_type();
|
||||||
_deleted_chain = memory_hook->get_deleted_chain(alloc_size);
|
_deleted_chain = DeletedBufferChain::get_deleted_chain(alloc_size);
|
||||||
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
||||||
|
|
||||||
for (size_t i = 0; i < _num_entries; ++i) {
|
for (size_t i = 0; i < _num_entries; ++i) {
|
||||||
@ -106,7 +106,7 @@ operator = (const SimpleHashMap<Key, Value, Compare> ©) {
|
|||||||
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
||||||
|
|
||||||
init_type();
|
init_type();
|
||||||
_deleted_chain = memory_hook->get_deleted_chain(alloc_size);
|
_deleted_chain = DeletedBufferChain::get_deleted_chain(alloc_size);
|
||||||
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
||||||
for (size_t i = 0; i < _num_entries; ++i) {
|
for (size_t i = 0; i < _num_entries; ++i) {
|
||||||
new(&_table[i]) TableEntry(copy._table[i]);
|
new(&_table[i]) TableEntry(copy._table[i]);
|
||||||
@ -691,7 +691,7 @@ new_table() {
|
|||||||
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity);
|
||||||
|
|
||||||
init_type();
|
init_type();
|
||||||
_deleted_chain = memory_hook->get_deleted_chain(alloc_size);
|
_deleted_chain = DeletedBufferChain::get_deleted_chain(alloc_size);
|
||||||
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
||||||
memset(get_index_array(), -1, _table_size * sizeof(int) * sparsity);
|
memset(get_index_array(), -1, _table_size * sizeof(int) * sparsity);
|
||||||
}
|
}
|
||||||
@ -749,7 +749,7 @@ resize_table(size_t new_size) {
|
|||||||
// We allocate enough bytes for _table_size elements of TableEntry, plus
|
// We allocate enough bytes for _table_size elements of TableEntry, plus
|
||||||
// _table_size * sparsity more ints at the end (for the sparse index array).
|
// _table_size * sparsity more ints at the end (for the sparse index array).
|
||||||
size_t alloc_size = _table_size * sizeof(TableEntry) + _table_size * sparsity * sizeof(int);
|
size_t alloc_size = _table_size * sizeof(TableEntry) + _table_size * sparsity * sizeof(int);
|
||||||
_deleted_chain = memory_hook->get_deleted_chain(alloc_size);
|
_deleted_chain = DeletedBufferChain::get_deleted_chain(alloc_size);
|
||||||
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
_table = (TableEntry *)_deleted_chain->allocate(alloc_size, _type_handle);
|
||||||
int *index_array = get_index_array();
|
int *index_array = get_index_array();
|
||||||
memset(index_array, -1, _table_size * sizeof(int) * sparsity);
|
memset(index_array, -1, _table_size * sizeof(int) * sparsity);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user