From 20abea52892a4ae47fed7d19348eca0e7513c88b Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Thu, 18 Dec 2025 19:41:47 -0500 Subject: [PATCH] xo-alloc: streamlining DArena allocation: + construct_with() helper --- xo-alloc2/include/xo/alloc2/arena/DArena.hpp | 23 ++++++++++++++++++ xo-alloc2/src/alloc2/DArena.cpp | 24 +++++++++++++++++++ xo-alloc2/src/alloc2/DArenaIterator.cpp | 22 ++--------------- xo-alloc2/src/alloc2/IAllocator_DArena.cpp | 12 ++-------- .../src/alloc2/IAllocator_DX1Collector.cpp | 14 ++--------- 5 files changed, 53 insertions(+), 42 deletions(-) diff --git a/xo-alloc2/include/xo/alloc2/arena/DArena.hpp b/xo-alloc2/include/xo/alloc2/arena/DArena.hpp index 580c6958b..36e87c4d 100644 --- a/xo-alloc2/include/xo/alloc2/arena/DArena.hpp +++ b/xo-alloc2/include/xo/alloc2/arena/DArena.hpp @@ -100,6 +100,13 @@ namespace xo { /** @ret iterator pointing to just after the last allocation in this arena **/ DArenaIterator end() const noexcept; + /** @ret header for first allocation in this arena **/ + AllocHeader * begin_header() const noexcept; + /** @ret location of header for next (not yet performed!) + * allocation in this arena + **/ + AllocHeader * end_header() const noexcept; + /** get header from allocated object address **/ header_type * obj2hdr(void * obj) noexcept; @@ -208,6 +215,22 @@ namespace xo { ///@} }; + /** construct a @tparam T instance from arguments @p args + * using memory obtained from arena @p ialloc + **/ + template + static T * + construct_with(DArena & ialloc, Args&&... args) + { + std::byte * mem = ialloc.alloc(sizeof(T)); + + if (mem) + return new (mem) T(std::forward(args)...); + + return nullptr; + } + } /*namespace mm*/ } /*namespace xo*/ diff --git a/xo-alloc2/src/alloc2/DArena.cpp b/xo-alloc2/src/alloc2/DArena.cpp index 6a0b40ed..d9dd832d 100644 --- a/xo-alloc2/src/alloc2/DArena.cpp +++ b/xo-alloc2/src/alloc2/DArena.cpp @@ -290,6 +290,30 @@ namespace xo { return DArenaIterator::end(this); } + AllocHeader * + DArena::begin_header() const noexcept + { + if (config_.store_header_flag_ == false) { + this->capture_error(error::alloc_iterator_not_supported); + + return nullptr; + } + + return (AllocHeader *)lo_; + } + + AllocHeader * + DArena::end_header() const noexcept + { + if (config_.store_header_flag_ == false) { + this->capture_error(error::alloc_iterator_not_supported); + + return nullptr; + } + + return (AllocHeader *)free_; + } + std::byte * DArena::alloc(std::size_t req_z) { diff --git a/xo-alloc2/src/alloc2/DArenaIterator.cpp b/xo-alloc2/src/alloc2/DArenaIterator.cpp index 65258eba..b9873e31 100644 --- a/xo-alloc2/src/alloc2/DArenaIterator.cpp +++ b/xo-alloc2/src/alloc2/DArenaIterator.cpp @@ -50,16 +50,7 @@ namespace xo { { assert(arena); - if (arena->config_.store_header_flag_ == false) { - arena->capture_error(error::alloc_iterator_not_supported); - - return nullptr; - } - - byte * begin_byte = arena->lo_; - AllocHeader * begin_hdr = (AllocHeader *)begin_byte; - - return begin_hdr; + return arena->begin_header(); } AllocHeader * @@ -67,16 +58,7 @@ namespace xo { { assert(arena); - if (arena->config_.store_header_flag_ == false) { - arena->capture_error(error::alloc_iterator_not_supported); - - return nullptr; - } - - byte * end_byte = arena->free_; - AllocHeader * end_hdr = (AllocHeader *)end_byte; - - return end_hdr; + return arena->end_header(); } AllocInfo diff --git a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp index 2e5af3c5..a9edc22a 100644 --- a/xo-alloc2/src/alloc2/IAllocator_DArena.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_DArena.cpp @@ -74,16 +74,8 @@ namespace xo { IAllocator_DArena::alloc_range(const DArena & s, DArena & ialloc) noexcept -> range_type { - byte * begin_mem = IAllocator_DArena::alloc(ialloc, - sizeof(DArenaIterator)); - byte * end_mem = IAllocator_DArena::alloc(ialloc, - sizeof(DArenaIterator)); - - assert(begin_mem); - assert(end_mem); - - DArenaIterator * begin_ix = new (begin_mem) DArenaIterator(&s, DArenaIterator::begin_header(&s)); - DArenaIterator * end_ix = new ( end_mem) DArenaIterator(&s, DArenaIterator::end_header(&s)); + DArenaIterator * begin_ix = construct_with(ialloc, &s, s.begin_header()); + DArenaIterator * end_ix = construct_with(ialloc, &s, s.end_header()); obj begin_obj = with_facet::mkobj(begin_ix); obj end_obj = with_facet::mkobj( end_ix); diff --git a/xo-alloc2/src/alloc2/IAllocator_DX1Collector.cpp b/xo-alloc2/src/alloc2/IAllocator_DX1Collector.cpp index ffebc138..f91f1d33 100644 --- a/xo-alloc2/src/alloc2/IAllocator_DX1Collector.cpp +++ b/xo-alloc2/src/alloc2/IAllocator_DX1Collector.cpp @@ -70,18 +70,8 @@ namespace xo { IAllocator_DX1Collector::alloc_range(const DX1Collector & d, DArena & ialloc) noexcept -> range_type { - byte * begin_mem = IAllocator_DArena::alloc(ialloc, - sizeof(DX1CollectorIterator)); - byte * end_mem = IAllocator_DArena::alloc(ialloc, - sizeof(DX1CollectorIterator)); - - assert(begin_mem); - assert(end_mem); - - DX1CollectorIterator * begin_ix - = new (begin_mem) DX1CollectorIterator(d.begin()); - DX1CollectorIterator * end_ix - = new ( end_mem) DX1CollectorIterator(d.end()); + DX1CollectorIterator * begin_ix = construct_with(ialloc, d.begin()); + DX1CollectorIterator * end_ix = construct_with(ialloc, d.end()); obj begin_obj = with_facet::mkobj(begin_ix); obj end_obj = with_facet::mkobj( end_ix);