xo-alloc / xo-object: utest coverage + assorted bugfixes

This commit is contained in:
Roland Conybeare 2025-08-07 18:32:14 -05:00
commit bd00826448
34 changed files with 1069 additions and 326 deletions

View file

@ -15,36 +15,20 @@ namespace xo {
*
* @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<ArenaAlloc> make(const std::string & name,
#ifdef REDLINE_MEMORY
std::size_t redline_z,
#endif
std::size_t z,
bool debug_flag);
@ -56,7 +40,7 @@ namespace xo {
// inherited from IAlloc...
virtual const std::string & name() const final override { return name_; }
virtual const std::string & name() const final override;
virtual std::size_t size() const final override;
virtual std::size_t available() const final override;
virtual std::size_t allocated() const final override;
@ -64,19 +48,14 @@ namespace xo {
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 bool debug_flag() const final override;
virtual void clear() final override;
virtual void checkpoint() final override;
virtual std::byte * alloc(std::size_t z) final override;
#ifdef REDLINE_MEMORY
virtual void release_redline_memory() final override;
#endif
private:
ArenaAlloc(const std::string & name,
#ifdef REDLINE_MEMORY
std::size_t rz,
#endif
std::size_t z, bool debug_flag);
private:
@ -99,10 +78,6 @@ namespace xo {
std::byte * free_ptr_ = nullptr;
/** soft limit: end of released memory **/
std::byte * limit_ = nullptr;
#ifdef REDLINE_MEMORY
/** amount of last-resort memory to reserve **/
std::size_t redline_z_ = 0;
#endif
/** hard limit: end of allocated memory **/
std::byte * hi_ = nullptr;
/** true to enable detailed debug logging **/

View file

@ -199,6 +199,15 @@ namespace xo {
#endif
private:
ListAlloc * nursery_to() const { return nursery(role::to_space); }
ListAlloc * nursery_from() const { return nursery(role::from_space); }
ListAlloc * tenured_to() const { return tenured(role::to_space); }
ListAlloc * tenured_from() const { return tenured(role::from_space); }
ListAlloc * nursery(role r) const { return nursery_[role2int(r)].get(); }
ListAlloc * tenured(role r) const { return tenured_[role2int(r)].get(); }
/** begin GC now **/
void execute_gc(generation g);
/** cleanup phase. aux function for @ref execute_gc **/

View file

@ -52,7 +52,7 @@ namespace xo {
/** 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; }
virtual bool debug_flag() const = 0;
/** reset allocator to empty state. **/
virtual void clear() = 0;
@ -76,10 +76,6 @@ namespace xo {
* Only used in @ref GC. Default implementation asserts and returns nullptr
**/
virtual std::byte * alloc_gc_copy(std::size_t z, const void * src);
#ifdef REDLINE_MEMORY
/** release last-resort reserved memory **/
virtual void release_redline_memory() = 0;
#endif
};
} /*namespace gc*/

View file

@ -29,9 +29,6 @@ namespace xo {
ListAlloc(std::unique_ptr<ArenaAlloc> hd,
ArenaAlloc * marked,
std::size_t cz, std::size_t nz, std::size_t tz,
#ifdef REDLINE_MEMORY
bool use_redline,
#endif
bool debug_flag);
~ListAlloc();
@ -40,8 +37,8 @@ namespace xo {
/** reset to have at least @p z bytes of storage **/
bool reset(std::size_t z);
/** expand bucket list to accomodate a requrest of size @p z **/
bool expand(std::size_t z);
/** expand bucket list to accomodate a request of size @p z **/
bool expand(std::size_t z, const std::string & name);
/** current free pointer **/
std::byte * free_ptr() const;
@ -64,13 +61,11 @@ namespace xo {
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 bool debug_flag() const final override;
virtual void clear() final override;
virtual void checkpoint() final override;
virtual std::byte * alloc(std::size_t z) final override;
#ifdef REDLINE_MEMORY
virtual void release_redline_memory() final override;
#endif
private:
/** **/
@ -89,11 +84,6 @@ namespace xo {
std::size_t next_z_ = 0;
/** total size of @ref hd_ + contents of @ref full_l_ **/
std::size_t total_z_ = 0;
#ifdef REDLINE_MEMORY
bool use_redline_ = false;
bool redlined_flag_ = false;
#endif
/** true to enable debug logging **/
bool debug_flag_ = false;
};

View file

@ -3,6 +3,9 @@
* author: Roland Conybeare, Aug 2025
*/
#pragma once
#include <ostream>
#include <cstdint>
namespace xo {
@ -15,6 +18,13 @@ namespace xo {
constexpr std::size_t gen2int(generation x) { return static_cast<std::size_t>(x); }
const char * gen2str(generation x);
inline std::ostream & operator<<(std::ostream & os, generation x) {
os << gen2str(x);
return os;
}
enum class generation_result {
nursery,
tenured,