From 750fbe44bd16135efd2c7f407b085b4c71f4a8d6 Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Thu, 22 Oct 2026 23:22:37 +0200 Subject: [PATCH] Removes legacy allocator functionality from lib --- source/lib/allocators/DynamicArena.h | 164 ------------------ source/lib/allocators/STLAllocators.h | 129 -------------- source/lib/allocators/allocator_checker.h | 76 -------- source/lib/allocators/overrun_protector.h | 101 ----------- .../lib/allocators/tests/test_DynamicArena.h | 75 -------- source/lib/allocators/tests/test_adapters.h | 82 --------- source/lib/config2.h | 10 -- 7 files changed, 637 deletions(-) delete mode 100644 source/lib/allocators/DynamicArena.h delete mode 100644 source/lib/allocators/STLAllocators.h delete mode 100644 source/lib/allocators/allocator_checker.h delete mode 100644 source/lib/allocators/overrun_protector.h delete mode 100644 source/lib/allocators/tests/test_DynamicArena.h delete mode 100644 source/lib/allocators/tests/test_adapters.h diff --git a/source/lib/allocators/DynamicArena.h b/source/lib/allocators/DynamicArena.h deleted file mode 100644 index a191552d82..0000000000 --- a/source/lib/allocators/DynamicArena.h +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (C) 2026 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef INCLUDED_ALLOCATORS_DYNAMIC_ARENA -#define INCLUDED_ALLOCATORS_DYNAMIC_ARENA - -#include "lib/bits.h" -#include "lib/code_annotation.h" -#include "lib/debug.h" - -#include -#include -#include // bad_alloc -#include -#include - -namespace Allocators { - -/** - * 'Blind' memory allocator. Characteristics: - * - grows dynamically, and linearily, by BLOCK_SIZE - * - no reallocations, pointers remain valid - * - can allocate objects up to BLOCK_SIZE in size - * - can handle any aligment (up to BLOCK_SIZE) - * - Doesn't de-allocate unless cleared or destroyed. - */ -template -class DynamicArena -{ -protected: - class Block - { - public: - Block() - { - m_Data = static_cast( - std::malloc(BLOCK_SIZE * sizeof(uint8_t))); - if (!m_Data) - { - debug_warn("DynamicArena failed to allocate chunk"); - throw std::bad_alloc(); - } - } - - ~Block() - { - std::free(static_cast(m_Data)); - } - - Block(const Block& other) = delete; - Block& operator=(const Block& other) = delete; - - Block(Block&& other) - : m_Size(other.m_Size), m_Data(other.m_Data) - { - other.m_Size = 0; - other.m_Data = nullptr; - } - - Block& operator=(Block&& other) - { - if (&other == this) - return *this; - - Block tmp(std::move(other)); - swap(*this, tmp); - - return *this; - } - - friend void swap(Block& lhs, Block& rhs) - { - using std::swap; - - swap(lhs.m_Size, rhs.m_Size); - swap(lhs.m_Data, rhs.m_Data); - } - - bool Available(size_t n, size_t alignment) const - { - return n + ROUND_UP(m_Size, alignment) <= BLOCK_SIZE; - } - - uint8_t* Allocate(size_t n, size_t alignment) - { - m_Size = ROUND_UP(m_Size, alignment); - uint8_t* ptr = &m_Data[m_Size]; - m_Size += n; - return ptr; - } - - private: - size_t m_Size = 0; - uint8_t* m_Data = nullptr; - }; - - NONCOPYABLE(DynamicArena); -public: - DynamicArena() - { - m_Blocks.reserve(16); - AllocateNewBlock(); - }; - - void AllocateNewBlock() - { - m_Blocks.emplace_back(); - } - - void* allocate(size_t n, size_t alignment) - { - // Safely handle zero-sized allocations (happens with GCC STL - see Issue #909). - if (n == 0) - n = 1; - - if (n > BLOCK_SIZE) - { - debug_warn("DynamicArena cannot allocate more than chunk size"); - throw std::bad_alloc(); - } - - if (!m_Blocks.back().Available(n, alignment)) - AllocateNewBlock(); - - return reinterpret_cast(m_Blocks.back().Allocate(n, alignment)); - } - - void deallocate(void*, size_t) - { - // ignored - } - - void clear() - { - m_Blocks.clear(); - AllocateNewBlock(); - } - -protected: - std::vector m_Blocks; -}; - -} // namespace Allocators - -#endif // INCLUDED_ALLOCATORS_DYNAMIC_ARENA diff --git a/source/lib/allocators/STLAllocators.h b/source/lib/allocators/STLAllocators.h deleted file mode 100644 index e93dbba843..0000000000 --- a/source/lib/allocators/STLAllocators.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (C) 2025 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef INCLUDED_STL_ALLOCATORS -#define INCLUDED_STL_ALLOCATORS - -#include -#include -#include - -/** - * Adapt a 0 A.D.-style allocator for usage in STL containers. - * Use 'Backend' as an underlying allocator. - */ -template -class STLAllocator -{ - template - friend class STLAllocator; -public: - using value_type = T; - using pointer = T*; - using is_always_equal = std::false_type; - - STLAllocator() : allocator(std::make_shared()) - { - } - - template - STLAllocator(const STLAllocator& proxy) : allocator(proxy.allocator) - { - } - - template - struct rebind - { - using other = STLAllocator; - }; - - T* allocate(size_t n) - { - return static_cast(allocator->allocate(n * sizeof(T), alignof(T))); - } - - void deallocate(T* ptr, const size_t n) - { - return allocator->deallocate(static_cast(ptr), n * sizeof(T)); - } - -private: - std::shared_ptr allocator; -}; - - -/** - * Proxies allocation to another allocator. - * This allows a single allocator to serve multiple STL containers. - */ -template -class ProxyAllocator -{ - template - friend class ProxyAllocator; -public: - using value_type = T; - using pointer = T*; - using is_always_equal = std::false_type; - - ProxyAllocator(Backend& alloc) : allocator(alloc) - { - } - - template - ProxyAllocator(const ProxyAllocator& proxy) : allocator(proxy.allocator) - { - } - - template - struct rebind - { - using other = ProxyAllocator; - }; - - T* allocate(size_t n) - { - return static_cast(allocator.allocate(n * sizeof(T), alignof(T))); - } - - void deallocate(T* ptr, const size_t n) - { - return allocator.deallocate(static_cast(ptr), n * sizeof(T)); - } - - template - bool operator==(const ProxyAllocator& other) const - { - return std::addressof(allocator) == std::addressof(other.allocator); - } - - template - bool operator!=(const ProxyAllocator& other) const - { - return std::addressof(allocator) != std::addressof(other.allocator); - } - -private: - Backend& allocator; -}; - -#endif // INCLUDED_STL_ALLOCATORS diff --git a/source/lib/allocators/allocator_checker.h b/source/lib/allocators/allocator_checker.h deleted file mode 100644 index 50b634c877..0000000000 --- a/source/lib/allocators/allocator_checker.h +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (C) 2025 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef INCLUDED_ALLOCATORS_ALLOCATOR_CHECKER -#define INCLUDED_ALLOCATORS_ALLOCATOR_CHECKER - -#include "lib/debug.h" -#include "lib/status.h" - -#include -#include -#include - -/** - * allocator test rig. - * call from each allocator operation to sanity-check them. - * should only be used during debug mode due to serious overhead. - **/ -class AllocatorChecker -{ -public: - void OnAllocate(void* p, size_t size) - { - const Allocs::value_type item = std::make_pair(p, size); - std::pair ret = allocs.insert(item); - ENSURE(ret.second == true); // wasn't already in map - } - - void OnDeallocate(void* p, size_t size) - { - Allocs::iterator it = allocs.find(p); - if(it == allocs.end()) - DEBUG_WARN_ERR(ERR::LOGIC); // freeing invalid pointer - else - { - // size must match what was passed to OnAllocate - const size_t allocated_size = it->second; - ENSURE(size == allocated_size); - - allocs.erase(it); - } - } - - /** - * allocator is resetting itself, i.e. wiping out all allocs. - **/ - void OnClear() - { - allocs.clear(); - } - -private: - typedef std::map Allocs; - Allocs allocs; -}; - -#endif // #ifndef INCLUDED_ALLOCATORS_ALLOCATOR_CHECKER diff --git a/source/lib/allocators/overrun_protector.h b/source/lib/allocators/overrun_protector.h deleted file mode 100644 index 787f9e273a..0000000000 --- a/source/lib/allocators/overrun_protector.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (C) 2025 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR -#define INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR - -#include "lib/code_annotation.h" -#include "lib/config2.h" // CONFIG2_ALLOCATORS_OVERRUN_PROTECTION - -/** -OverrunProtector wraps an arbitrary object in isolated page(s) and -can detect inadvertent writes to it. this is useful for -tracking down memory overruns. - -the basic idea is to require users to request access to the object and -notify us when done; memory access permission is temporarily granted. -(similar in principle to Software Transaction Memory). - -since this is quite slow, the protection is disabled unless -CONFIG2_ALLOCATORS_OVERRUN_PROTECTION == 1; this avoids having to remove the -wrapper code in release builds and re-write when looking for overruns. - -example usage: -OverrunProtector\ wrapper; -.. -T* p = wrapper.get(); // unlock, make ready for use -if(!p) // wrapper's one-time alloc of a T- - abort(); // instance had failed - can't continue. -DoSomethingWith(p); // (read/write access) -wrapper.lock(); // disallow further access until next .get() -.. -**/ -template class OverrunProtector -{ - NONCOPYABLE(OverrunProtector); // const member -public: - OverrunProtector() -#if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION - : object(new(vm::Allocate(sizeof(T))) T()) -#else - : object(new T()) -#endif - { - lock(); - } - - ~OverrunProtector() - { - unlock(); -#if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION - object->~T(); // call dtor (since we used placement new) - vm::Free(object, sizeof(T)); -#else - delete object; -#endif - } - - T* get() const - { - unlock(); - return object; - } - - void lock() const - { -#if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION - vm::Protect(object, sizeof(T), PROT_NONE); -#endif - } - -private: - void unlock() const - { -#if CONFIG2_ALLOCATORS_OVERRUN_PROTECTION - vm::Protect(object, sizeof(T), PROT_READ|PROT_WRITE); -#endif - } - - T* const object; -}; - -#endif // #ifndef INCLUDED_ALLOCATORS_OVERRUN_PROTECTOR diff --git a/source/lib/allocators/tests/test_DynamicArena.h b/source/lib/allocators/tests/test_DynamicArena.h deleted file mode 100644 index 9760ae3b2b..0000000000 --- a/source/lib/allocators/tests/test_DynamicArena.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (C) 2026 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "lib/self_test.h" - -#include "lib/allocators/DynamicArena.h" - -class TestDynamicArena : public CxxTest::TestSuite -{ -public: - void test_allocate() - { - Allocators::DynamicArena<100> testArena; - std::uint8_t* p = static_cast(testArena.allocate(10, 1)); - TS_ASSERT(p != nullptr); - void* p2 = testArena.allocate(10, 1); - TS_ASSERT(p + 10 == p2); - - void* p3 = testArena.allocate(80, 1); - TS_ASSERT(p + 20 == p3); - - void* p4 = testArena.allocate(100, 1); - TS_ASSERT(p4 != nullptr); - - void* p5 = testArena.allocate(1, 1); - TS_ASSERT(p5 != nullptr); - - void* p6 = testArena.allocate(100, 1); - TS_ASSERT(p6 != nullptr); - - void* p7 = testArena.allocate(0, 1); - TS_ASSERT(p7 != nullptr); - } - - void test_alignment() - { - Allocators::DynamicArena<100> testArena; - std::uint8_t* p = static_cast(testArena.allocate(4, 1)); - TS_ASSERT(p != nullptr); - - std::uint8_t* p2 = static_cast(testArena.allocate(1, 8)); - TS_ASSERT_EQUALS(p + 8, p2); - - p2 = static_cast(testArena.allocate(1, 8)); - TS_ASSERT_EQUALS(p + 16, p2); - - p2 = static_cast(testArena.allocate(1, 8)); - TS_ASSERT_EQUALS(p + 24, p2); - - p2 = static_cast(testArena.allocate(1, 2)); - TS_ASSERT_EQUALS(p + 26, p2); - - p2 = static_cast(testArena.allocate(1, 8)); - TS_ASSERT_EQUALS(p + 32, p2); - } -}; diff --git a/source/lib/allocators/tests/test_adapters.h b/source/lib/allocators/tests/test_adapters.h deleted file mode 100644 index 108e6d588b..0000000000 --- a/source/lib/allocators/tests/test_adapters.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (C) 2025 Wildfire Games. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "lib/self_test.h" - -#include "lib/allocators/DynamicArena.h" -#include "lib/allocators/STLAllocators.h" - -#include -#include -#include -#include -#include - -class TestSTLAllocators : public CxxTest::TestSuite -{ -public: - struct SomeData - { - SomeData(int) {}; - int padding[10]; - }; - - template typename Alloc, typename D> - using Allocator = Alloc>; - - template typename Alloc> - using Map = std::map, Allocator::value_type>>; - - template typename Alloc> - using UMap = std::unordered_map, std::equal_to, Allocator::value_type>>; - - void test_CustomAllocator() - { - Map map; - UMap umap; - std::vector>> vec; - - map.emplace(4, 5); - umap.emplace(4, 5); - vec.emplace_back(5); - - map.clear(); - umap.clear(); - vec.clear(); - } - - void test_ProxyAllocator() - { - Allocators::DynamicArena<4096> arena; - Map map(arena); - UMap umap(arena); - std::vector> vec(arena); - - map.emplace(4, 5); - umap.emplace(4, 5); - vec.emplace_back(5); - - map.clear(); - umap.clear(); - vec.clear(); - } -}; diff --git a/source/lib/config2.h b/source/lib/config2.h index 879c7ab68f..61c66fa1f9 100644 --- a/source/lib/config2.h +++ b/source/lib/config2.h @@ -36,16 +36,6 @@ # define CONFIG2_DAP_INTERFACE 1 #endif // !CONFIG2_DAP_INTERFACE -// this enables/disables the actual checking done by OverrunProtector -// (quite slow, entailing mprotect() before/after each access). -// define to 1 here or in the relevant module if you suspect mem corruption. -// we provide this option because OverrunProtector requires some changes to -// the object being wrapped, and we want to leave those intact but not -// significantly slow things down except when needed. -#ifndef CONFIG2_ALLOCATORS_OVERRUN_PROTECTION -# define CONFIG2_ALLOCATORS_OVERRUN_PROTECTION 0 -#endif - #ifndef CONFIG2_FILE_ENABLE_AIO // work around a bug introduced in Linux 2.6.38 // (http://www.wildfiregames.com/forum/index.php?showtopic=14561&view=findpost&p=217710)