From bf65624298b9a5ea49cb637fadb4fc6f7c85ce9b Mon Sep 17 00:00:00 2001 From: rdb Date: Sun, 23 Oct 2022 14:55:59 +0200 Subject: [PATCH] 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 --- dtool/src/dtoolbase/CMakeLists.txt | 2 +- dtool/src/dtoolbase/deletedBufferChain.I | 52 +++++++++++ dtool/src/dtoolbase/deletedBufferChain.cxx | 51 ++++++++--- dtool/src/dtoolbase/deletedBufferChain.h | 20 ++++- .../{deletedChain.T => deletedChain.I} | 9 +- dtool/src/dtoolbase/deletedChain.h | 2 +- dtool/src/dtoolbase/dtoolbase.cxx | 26 ++---- dtool/src/dtoolbase/memoryHook.I | 6 ++ dtool/src/dtoolbase/memoryHook.cxx | 87 ++++++------------- dtool/src/dtoolbase/memoryHook.h | 25 +++--- dtool/src/dtoolbase/typeRegistry.cxx | 1 - dtool/src/prc/configVariableManager.cxx | 1 - dtool/src/prc/notify.cxx | 1 - panda/src/event/asyncTaskManager.cxx | 1 - panda/src/event/eventHandler.cxx | 1 - panda/src/event/eventQueue.cxx | 1 - panda/src/express/memoryUsage.cxx | 1 - panda/src/movies/movieVideoCursor.cxx | 2 +- panda/src/pipeline/thread.cxx | 2 - panda/src/putil/simpleHashMap.I | 8 +- 20 files changed, 166 insertions(+), 133 deletions(-) rename dtool/src/dtoolbase/{deletedChain.T => deletedChain.I} (96%) diff --git a/dtool/src/dtoolbase/CMakeLists.txt b/dtool/src/dtoolbase/CMakeLists.txt index cd2e8a1fc3..7e9340ec71 100644 --- a/dtool/src/dtoolbase/CMakeLists.txt +++ b/dtool/src/dtoolbase/CMakeLists.txt @@ -21,7 +21,7 @@ set(P3DTOOLBASE_HEADERS atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I cmath.I cmath.h deletedBufferChain.h deletedBufferChain.I - deletedChain.h deletedChain.T + deletedChain.h deletedChain.I dtoolbase.h dtoolbase_cc.h dtoolsymbols.h dtool_platform.h fakestringstream.h diff --git a/dtool/src/dtoolbase/deletedBufferChain.I b/dtool/src/dtoolbase/deletedBufferChain.I index ac5243de76..f74c9dd5eb 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.I +++ b/dtool/src/dtoolbase/deletedBufferChain.I @@ -11,6 +11,34 @@ * @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 * was never a valid pointer. @@ -41,6 +69,30 @@ get_buffer_size() const { 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. */ diff --git a/dtool/src/dtoolbase/deletedBufferChain.cxx b/dtool/src/dtoolbase/deletedBufferChain.cxx index d38b833ea1..e1596773c5 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.cxx +++ b/dtool/src/dtoolbase/deletedBufferChain.cxx @@ -14,18 +14,34 @@ #include "deletedBufferChain.h" #include "memoryHook.h" -/** - * 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; +#include - // We must allocate at least this much space for bookkeeping reasons. - _buffer_size = std::max(_buffer_size, sizeof(ObjectNode)); -} +DeletedBufferChain DeletedBufferChain::_small_deleted_chains[DeletedBufferChain::num_small_deleted_chains] = { + 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 @@ -139,3 +155,16 @@ deallocate(void *ptr, TypeHandle type_handle) { PANDA_FREE_SINGLE(ptr); #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 deleted_chains; + DeletedBufferChain *result = (DeletedBufferChain *)&*deleted_chains.insert(DeletedBufferChain(buffer_size)).first; + lock.unlock(); + return result; +} diff --git a/dtool/src/dtoolbase/deletedBufferChain.h b/dtool/src/dtoolbase/deletedBufferChain.h index 3bfd8cc071..25adf6ce5e 100644 --- a/dtool/src/dtoolbase/deletedBufferChain.h +++ b/dtool/src/dtoolbase/deletedBufferChain.h @@ -58,16 +58,25 @@ enum DeletedChainFlag : unsigned int { */ class EXPCL_DTOOL_DTOOLBASE DeletedBufferChain { protected: - DeletedBufferChain(size_t buffer_size); + constexpr explicit DeletedBufferChain(size_t buffer_size); public: + INLINE DeletedBufferChain(DeletedBufferChain &&from) noexcept; + INLINE DeletedBufferChain(const DeletedBufferChain ©); + void *allocate(size_t size, TypeHandle type_handle); void deallocate(void *ptr, TypeHandle type_handle); INLINE bool validate(void *ptr); 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: + static DeletedBufferChain *get_large_deleted_chain(size_t buffer_size); + class ObjectNode { public: #ifdef USE_DELETEDCHAINFLAG @@ -87,10 +96,10 @@ private: static INLINE void *node_to_buffer(ObjectNode *node); static INLINE ObjectNode *buffer_to_node(void *buffer); - ObjectNode *_deleted_chain; + ObjectNode *_deleted_chain = nullptr; MutexImpl _lock; - size_t _buffer_size; + const size_t _buffer_size; #ifndef USE_DELETEDCHAINFLAG // 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); #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; }; diff --git a/dtool/src/dtoolbase/deletedChain.T b/dtool/src/dtoolbase/deletedChain.I similarity index 96% rename from dtool/src/dtoolbase/deletedChain.T rename to dtool/src/dtoolbase/deletedChain.I index 96e800ba3b..53ad023c67 100644 --- a/dtool/src/dtoolbase/deletedChain.T +++ b/dtool/src/dtoolbase/deletedChain.I @@ -6,7 +6,7 @@ * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * - * @file deletedChain.T + * @file deletedChain.I * @author drose * @date 2006-04-01 */ @@ -82,7 +82,7 @@ validate(const Type *ptr) { template INLINE ReferenceCount *DeletedChain:: make_ref_ptr(void *) { - return NULL; + return nullptr; } /** @@ -106,9 +106,8 @@ make_ref_ptr(ReferenceCount *ptr) { template void DeletedChain:: init_deleted_chain() { - if (_chain == (DeletedBufferChain *)NULL) { - init_memory_hook(); - _chain = memory_hook->get_deleted_chain(sizeof(Type)); + if (_chain == nullptr) { + _chain = DeletedBufferChain::get_deleted_chain(sizeof(Type)); } } diff --git a/dtool/src/dtoolbase/deletedChain.h b/dtool/src/dtoolbase/deletedChain.h index a72bc85f96..a1b08a31bf 100644 --- a/dtool/src/dtoolbase/deletedChain.h +++ b/dtool/src/dtoolbase/deletedChain.h @@ -136,6 +136,6 @@ public: #endif // USE_DELETED_CHAIN -#include "deletedChain.T" +#include "deletedChain.I" #endif diff --git a/dtool/src/dtoolbase/dtoolbase.cxx b/dtool/src/dtoolbase/dtoolbase.cxx index 0b7c874db2..926d8cd61a 100644 --- a/dtool/src/dtoolbase/dtoolbase.cxx +++ b/dtool/src/dtoolbase/dtoolbase.cxx @@ -23,34 +23,18 @@ bool __tau_shutdown = false; #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 - * of the global memory_hook object, at static init time, should ensure that - * 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. + * It used to be necessary to call this before using operator new at static + * init time. There is no need to call this function anymore. */ void init_memory_hook() { - if (memory_hook == nullptr) { - memory_hook = new MemoryHook; - } + assert(memory_hook != nullptr); } -// 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) static void diff --git a/dtool/src/dtoolbase/memoryHook.I b/dtool/src/dtoolbase/memoryHook.I index cc4f972f6b..d44289e5f9 100644 --- a/dtool/src/dtoolbase/memoryHook.I +++ b/dtool/src/dtoolbase/memoryHook.I @@ -40,6 +40,9 @@ dec_heap(size_t size) { */ INLINE size_t MemoryHook:: get_page_size() const { + if (_page_size == 0) { + determine_page_size(); + } return _page_size; } @@ -49,6 +52,9 @@ get_page_size() const { */ INLINE size_t MemoryHook:: 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; } diff --git a/dtool/src/dtoolbase/memoryHook.cxx b/dtool/src/dtoolbase/memoryHook.cxx index 8712099ab7..60e7695522 100644 --- a/dtool/src/dtoolbase/memoryHook.cxx +++ b/dtool/src/dtoolbase/memoryHook.cxx @@ -198,33 +198,6 @@ ptr_to_alloc(void *ptr, size_t &size) { #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), _max_heap_size(copy._max_heap_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 @@ -522,6 +483,9 @@ heap_trim(size_t pad) { */ void *MemoryHook:: mmap_alloc(size_t size, bool allow_exec) { + if (_page_size == 0) { + determine_page_size(); + } assert((size % _page_size) == 0); #ifdef DO_MEMORY_USAGE @@ -576,6 +540,7 @@ mmap_alloc(size_t size, bool allow_exec) { */ void MemoryHook:: mmap_free(void *ptr, size_t size) { + assert(_page_size != 0); assert((size % _page_size) == 0); #ifdef DO_MEMORY_USAGE @@ -601,29 +566,6 @@ void MemoryHook:: 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() * has returned NULL, indicating failure. @@ -656,3 +598,24 @@ overflow_heap_size() { _max_heap_size = ~(size_t)0; #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); +} diff --git a/dtool/src/dtoolbase/memoryHook.h b/dtool/src/dtoolbase/memoryHook.h index 11d83439d3..d0726c5895 100644 --- a/dtool/src/dtoolbase/memoryHook.h +++ b/dtool/src/dtoolbase/memoryHook.h @@ -20,8 +20,6 @@ #include "mutexImpl.h" #include -class DeletedBufferChain; - /** * This class provides a wrapper around the various possible malloc schemes * Panda might employ. It also exists to allow the MemoryUsage class in Panda @@ -36,9 +34,9 @@ class DeletedBufferChain; */ class EXPCL_DTOOL_DTOOLBASE MemoryHook { public: - MemoryHook(); + constexpr MemoryHook() = default; MemoryHook(const MemoryHook ©); - virtual ~MemoryHook(); + virtual ~MemoryHook() = default; virtual void *heap_alloc_single(size_t size); 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); - DeletedBufferChain *get_deleted_chain(size_t buffer_size); - virtual void alloc_fail(size_t attempted_size); INLINE static size_t get_ptr_size(void *ptr); protected: - TVOLATILE AtomicAdjust::Integer _total_heap_single_size; - TVOLATILE AtomicAdjust::Integer _total_heap_array_size; - TVOLATILE AtomicAdjust::Integer _requested_heap_size; - TVOLATILE AtomicAdjust::Integer _total_mmap_size; + TVOLATILE AtomicAdjust::Integer _total_heap_single_size = 0; + TVOLATILE AtomicAdjust::Integer _total_heap_array_size = 0; + TVOLATILE AtomicAdjust::Integer _requested_heap_size = 0; + TVOLATILE AtomicAdjust::Integer _total_mmap_size = 0; // If the allocated heap size crosses this threshold, we call // overflow_heap_size(). - size_t _max_heap_size; + size_t _max_heap_size = ~(size_t)0; virtual void overflow_heap_size(); -private: - size_t _page_size; + void determine_page_size() const; - typedef std::map DeletedChains; - DeletedChains _deleted_chains; +private: + mutable size_t _page_size = 0; mutable MutexImpl _lock; }; diff --git a/dtool/src/dtoolbase/typeRegistry.cxx b/dtool/src/dtoolbase/typeRegistry.cxx index f2646eddb9..0633f5b984 100644 --- a/dtool/src/dtoolbase/typeRegistry.cxx +++ b/dtool/src/dtoolbase/typeRegistry.cxx @@ -539,7 +539,6 @@ TypeRegistry() { */ void TypeRegistry:: init_global_pointer() { - init_memory_hook(); _global_pointer = new TypeRegistry; } diff --git a/dtool/src/prc/configVariableManager.cxx b/dtool/src/prc/configVariableManager.cxx index 86375764e4..8097acae0d 100644 --- a/dtool/src/prc/configVariableManager.cxx +++ b/dtool/src/prc/configVariableManager.cxx @@ -28,7 +28,6 @@ ConfigVariableManager *ConfigVariableManager::_global_ptr = nullptr; */ ConfigVariableManager:: ConfigVariableManager() { - init_memory_hook(); } /** diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx index 2a82f2926d..9528ed9903 100644 --- a/dtool/src/prc/notify.cxx +++ b/dtool/src/prc/notify.cxx @@ -291,7 +291,6 @@ write_string(const string &str) { Notify *Notify:: ptr() { if (_global_ptr == nullptr) { - init_memory_hook(); _global_ptr = new Notify; } return _global_ptr; diff --git a/panda/src/event/asyncTaskManager.cxx b/panda/src/event/asyncTaskManager.cxx index b10c7ea935..48d3ac5bfc 100644 --- a/panda/src/event/asyncTaskManager.cxx +++ b/panda/src/event/asyncTaskManager.cxx @@ -649,7 +649,6 @@ void AsyncTaskManager:: make_global_ptr() { nassertv(_global_ptr == nullptr); - init_memory_hook(); _global_ptr = new AsyncTaskManager("TaskManager"); _global_ptr->ref(); } diff --git a/panda/src/event/eventHandler.cxx b/panda/src/event/eventHandler.cxx index 5ad4bbe0e6..2adb7b1e6c 100644 --- a/panda/src/event/eventHandler.cxx +++ b/panda/src/event/eventHandler.cxx @@ -395,7 +395,6 @@ remove_all_hooks() { */ void EventHandler:: make_global_event_handler() { - init_memory_hook(); _global_event_handler = new EventHandler(EventQueue::get_global_event_queue()); } diff --git a/panda/src/event/eventQueue.cxx b/panda/src/event/eventQueue.cxx index cb060944c3..9ed00c38ea 100644 --- a/panda/src/event/eventQueue.cxx +++ b/panda/src/event/eventQueue.cxx @@ -108,6 +108,5 @@ dequeue_event() { */ void EventQueue:: make_global_event_queue() { - init_memory_hook(); _global_event_queue = new EventQueue; } diff --git a/panda/src/express/memoryUsage.cxx b/panda/src/express/memoryUsage.cxx index 15acc27cf0..bdc785222a 100644 --- a/panda/src/express/memoryUsage.cxx +++ b/panda/src/express/memoryUsage.cxx @@ -535,7 +535,6 @@ MemoryUsage(const MemoryHook ©) : void MemoryUsage:: init_memory_usage() { #ifdef DO_MEMORY_USAGE - init_memory_hook(); _global_ptr = new MemoryUsage(*memory_hook); memory_hook = _global_ptr; #else diff --git a/panda/src/movies/movieVideoCursor.cxx b/panda/src/movies/movieVideoCursor.cxx index 96ead8c8f0..3d76960027 100644 --- a/panda/src/movies/movieVideoCursor.cxx +++ b/panda/src/movies/movieVideoCursor.cxx @@ -363,7 +363,7 @@ MovieVideoCursor::Buffer:: Buffer(size_t 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()); } diff --git a/panda/src/pipeline/thread.cxx b/panda/src/pipeline/thread.cxx index 5f2cafda3a..d843eed257 100644 --- a/panda/src/pipeline/thread.cxx +++ b/panda/src/pipeline/thread.cxx @@ -209,7 +209,6 @@ init_main_thread() { static int count = 0; ++count; if (count == 1 && _main_thread == nullptr) { - init_memory_hook(); _main_thread = new MainThread; _main_thread->ref(); } @@ -221,7 +220,6 @@ init_main_thread() { void Thread:: init_external_thread() { if (_external_thread == nullptr) { - init_memory_hook(); _external_thread = new ExternalThread; _external_thread->ref(); } diff --git a/panda/src/putil/simpleHashMap.I b/panda/src/putil/simpleHashMap.I index 9b8dc07c24..d33b8bad34 100644 --- a/panda/src/putil/simpleHashMap.I +++ b/panda/src/putil/simpleHashMap.I @@ -46,7 +46,7 @@ SimpleHashMap(const SimpleHashMap ©) : size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity); 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); for (size_t i = 0; i < _num_entries; ++i) { @@ -106,7 +106,7 @@ operator = (const SimpleHashMap ©) { size_t alloc_size = _table_size * (sizeof(TableEntry) + sizeof(int) * sparsity); 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); for (size_t i = 0; i < _num_entries; ++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); 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); 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 // _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); - _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); int *index_array = get_index_array(); memset(index_array, -1, _table_size * sizeof(int) * sparsity);