/* file ArenaAlloc.hpp * * author: Roland Conybeare, Jul 2025 */ #pragma once #include "IAlloc.hpp" namespace xo { namespace gc { /** @class ArenaAlloc * @brief Bump allocator with fixed capacity * * @text * * before @ref release_redline_memory * * <-----allocated----> <-free-> <-reserved-> * XXXXXXXXXXXXXXXXXXXX______________________ * ^ ^ ^ ^ * lo free redline hi * limit * * after @ref release_redline_memory * * <-----allocated----> <--------free-------> * XXXXXXXXXXXXXXXXXXXX______________________ * ^ ^ ^ * lo free hi * limit * @endtext * * TODO: rename to ArenaAlloc **/ class ArenaAlloc : public IAlloc { public: ~ArenaAlloc(); /** create allocator with capacity @p z, * with reserved capacity @p redline_z. **/ static up make(const std::string & name, std::size_t redline_z, std::size_t z, bool debug_flag); std::byte * free_ptr() const { return free_ptr_; } void set_free_ptr(std::byte * x); // inherited from IAlloc... virtual const std::string & name() const final override { return name_; } virtual std::size_t size() const final override; virtual std::size_t available() const final override; virtual std::size_t allocated() const final override; virtual bool contains(const void * x) const final override; virtual bool is_before_checkpoint(const void * x) const final override; virtual std::size_t before_checkpoint() const final override; virtual std::size_t after_checkpoint() const final override; virtual void clear() final override; virtual void checkpoint() final override; virtual std::byte * alloc(std::size_t z) final override; virtual void release_redline_memory() final override; private: ArenaAlloc(const std::string & name, std::size_t rz, std::size_t z, bool debug_flag); private: /** * Invariants: * - @ref free_ always a multiple of word size (assumed to be sizeof(void*)) **/ /** optional instance name, for diagnostics **/ std::string name_; /** allocator owns memory in range [@ref lo_, @ref hi_) **/ std::byte * lo_ = nullptr; /** checkpoint (for GC support); divides objects into * older (addresses below checkpoint) * and younger (addresses above checkpoint) **/ std::byte * checkpoint_; /** free pointer. memory in range [@ref free_, @ref limit_) available **/ std::byte * free_ptr_ = nullptr; /** soft limit: end of released memory **/ std::byte * limit_ = nullptr; /** amount of last-resort memory to reserve **/ std::size_t redline_z_ = 0; /** hard limit: end of allocated memory **/ std::byte * hi_ = nullptr; /** true to enable detailed debug logging **/ bool debug_flag_ = false; }; } /*namespace gc*/ } /*namespace xo*/ /* end ArenaAlloc.hpp */