/* file IAlloc.hpp * * author: Roland Conybeare, Jul 2025 */ #pragma once #include #include namespace xo { template using up = std::unique_ptr; class Object; namespace gc { /** @class IAllocator * @brief memory allocation interface with limited garbaga collector support **/ class IAlloc { public: virtual ~IAlloc() {} /** compute padding to add to an allocation of size z to bring it up to * a multiple of word size (8 bytes on x86_64) **/ static std::uint32_t alloc_padding(std::size_t z); /** z + alloc_padding(z) **/ static std::size_t with_padding(std::size_t z); /** optional name for this allocator; labelling for diagnostics **/ virtual const std::string & name() const = 0; /** allocator size in bytes (up to soft limit). * Includes unallocated mmeory **/ virtual std::size_t size() const = 0; /** number of unallocated bytes available (up to soft limit) * from this allocator **/ virtual std::size_t available() const = 0; /** number of bytes allocated from this allocator **/ virtual std::size_t allocated() const = 0; /** true iff pointer x comes from this allocator **/ virtual bool contains(const void * x) const = 0; /** true iff object at address @p x was allocated by this allocator, * and before checkpoint **/ virtual bool is_before_checkpoint(const void * x) const = 0; /** number of bytes allocated before @ref checkpoint **/ virtual std::size_t before_checkpoint() const = 0; /** number of bytes allocated since @ref checkpoint **/ virtual std::size_t after_checkpoint() const = 0; /** @return true iff debug logging enabled **/ virtual bool debug_flag() const { return false; } /** reset allocator to empty state. **/ virtual void clear() = 0; /** remember allocator state. All currently-allocated addresses xo * will satisfy is_before_checkpoint(x). Subsequent allocations x * will fail is_before_checkpoint(x), until checkpoint superseded * by @ref clear or another call to @ref checkpoint **/ virtual void checkpoint() = 0; /** perform assignment * @code * *lhs = rhs * @endcode * plus additional book keeping if needed (e.g. in @ref GC) * Default implementation just does the assignment. **/ virtual void assign_member(Object * parent, Object ** lhs, Object * rhs); /** allocate @p z bytes of memory. returns pointer to first address **/ virtual std::byte * alloc(std::size_t z) = 0; /** allocate @p z bytes for copy of object at @p src. * Only used in @ref GC. Default implementation asserts and returns nullptr **/ virtual std::byte * alloc_gc_copy(std::size_t z, const void * src); /** release last-resort reserved memory **/ virtual void release_redline_memory() = 0; }; } /*namespace gc*/ class MMPtr { public: explicit MMPtr(gc::IAlloc * mm) : mm_{mm} {} gc::IAlloc * mm_ = nullptr; }; } /*namespace xo*/ inline void * operator new (std::size_t z, const xo::MMPtr & mmp) { return mmp.mm_->alloc(z); } //inline void operator delete (void * p, const MMPtr & mmp) { // mmp.mm_->free(reinterpret_cast(p)); //} inline void * operator new[] (std::size_t z, const xo::MMPtr & mmp) { return mmp.mm_->alloc(z); } //inline void operator delete[] (void * p, const MMPtr & mmp) { // mmp.mm_->free(reinterpret_cast(p)); //} /* end IAlloc.hpp */