LCOV - code coverage report
Current view: top level - asmjit - zonestack.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 32 34 94.1 %
Date: 2026-11-05 10:19:06 Functions: 4 4 100.0 %

          Line data    Source code
       1             : #ifdef __PLUMED_HAS_ASMJIT
       2             : // This file is part of AsmJit project <https://asmjit.com>
       3             : //
       4             : // See asmjit.h or LICENSE.md for license and copyright information
       5             : // SPDX-License-Identifier: Zlib
       6             : 
       7             : #ifndef ASMJIT_CORE_ZONESTACK_H_INCLUDED
       8             : #define ASMJIT_CORE_ZONESTACK_H_INCLUDED
       9             : 
      10             : #include "zone.h"
      11             : 
      12             : ASMJIT_BEGIN_NAMESPACE
      13             : 
      14             : //! \addtogroup asmjit_zone
      15             : //! \{
      16             : 
      17             : //! Base class used by \ref ZoneStack.
      18             : class ZoneStackBase {
      19             : public:
      20             :   ASMJIT_NONCOPYABLE(ZoneStackBase)
      21             : 
      22             :   //! \name Constants
      23             :   //! \{
      24             : 
      25             :   enum : size_t {
      26             :     kBlockIndexPrev = 0,
      27             :     kBlockIndexNext = 1,
      28             : 
      29             :     kBlockIndexFirst = 0,
      30             :     kBlockIndexLast = 1,
      31             : 
      32             :     kBlockSize = ZoneAllocator::kHiMaxSize
      33             :   };
      34             : 
      35             :   //! \}
      36             : 
      37             :   //! \name Types
      38             :   //! \{
      39             : 
      40             :   struct Block {
      41             :     //! Next and previous blocks.
      42             :     Block* _link[2];
      43             :     //! Pointer to the start of the array.
      44             :     void* _start;
      45             :     //! Pointer to the end of the array.
      46             :     void* _end;
      47             : 
      48       82476 :     inline bool empty() const noexcept { return _start == _end; }
      49             :     inline Block* prev() const noexcept { return _link[kBlockIndexPrev]; }
      50       54984 :     inline Block* next() const noexcept { return _link[kBlockIndexNext]; }
      51             : 
      52             :     inline void setPrev(Block* block) noexcept { _link[kBlockIndexPrev] = block; }
      53             :     inline void setNext(Block* block) noexcept { _link[kBlockIndexNext] = block; }
      54             : 
      55             :     template<typename T>
      56      192444 :     inline T* start() const noexcept { return static_cast<T*>(_start); }
      57             :     template<typename T>
      58       54984 :     inline void setStart(T* start) noexcept { _start = static_cast<void*>(start); }
      59             : 
      60             :     template<typename T>
      61      247428 :     inline T* end() const noexcept { return (T*)_end; }
      62             :     template<typename T>
      63      109968 :     inline void setEnd(T* end) noexcept { _end = (void*)end; }
      64             : 
      65             :     template<typename T>
      66             :     inline T* data() const noexcept { return (T*)((uint8_t*)(this) + sizeof(Block)); }
      67             : 
      68             :     template<typename T>
      69             :     inline bool canPrepend() const noexcept { return _start > data<void>(); }
      70             : 
      71             :     template<typename T>
      72             :     inline bool canAppend() const noexcept {
      73             :       size_t kNumBlockItems = (kBlockSize - sizeof(Block)) / sizeof(T);
      74             :       size_t kStartBlockIndex = sizeof(Block);
      75             :       size_t kEndBlockIndex = kStartBlockIndex + kNumBlockItems * sizeof(T);
      76             : 
      77       82476 :       return (uintptr_t)_end <= ((uintptr_t)this + kEndBlockIndex - sizeof(T));
      78             :     }
      79             :   };
      80             : 
      81             :   //! \}
      82             : 
      83             :   //! \name Members
      84             :   //! \{
      85             : 
      86             :   //! Allocator used to allocate data.
      87             :   ZoneAllocator* _allocator;
      88             :   //! First and last blocks.
      89             :   Block* _block[2];
      90             : 
      91             :   //! \}
      92             : 
      93             :   //! \name Construction & Destruction
      94             :   //! \{
      95             : 
      96       54984 :   inline ZoneStackBase() noexcept {
      97       54984 :     _allocator = nullptr;
      98       54984 :     _block[0] = nullptr;
      99       27492 :     _block[1] = nullptr;
     100             :   }
     101             :   inline ~ZoneStackBase() noexcept { reset(); }
     102             : 
     103             :   inline bool isInitialized() const noexcept { return _allocator != nullptr; }
     104             :   ASMJIT_API Error _init(ZoneAllocator* allocator, size_t middleIndex) noexcept;
     105       82476 :   inline Error reset() noexcept { return _init(nullptr, 0); }
     106             : 
     107             :   //! \}
     108             : 
     109             :   //! \name Accessors
     110             :   //! \{
     111             : 
     112             :   //! Returns `ZoneAllocator` attached to this container.
     113             :   inline ZoneAllocator* allocator() const noexcept { return _allocator; }
     114             : 
     115             :   inline bool empty() const noexcept {
     116             :     ASMJIT_ASSERT(isInitialized());
     117      137460 :     return _block[0]->start<void>() == _block[1]->end<void>();
     118             :   }
     119             : 
     120             :   //! \}
     121             : 
     122             :   //! \cond INTERNAL
     123             :   //! \name Internal
     124             :   //! \{
     125             : 
     126             :   ASMJIT_API Error _prepareBlock(uint32_t side, size_t initialIndex) noexcept;
     127             :   ASMJIT_API void _cleanupBlock(uint32_t side, size_t middleIndex) noexcept;
     128             : 
     129             :   //! \}
     130             :   //! \endcond
     131             : };
     132             : 
     133             : //! Zone allocated stack container.
     134             : template<typename T>
     135             : class ZoneStack : public ZoneStackBase {
     136             : public:
     137             :   ASMJIT_NONCOPYABLE(ZoneStack)
     138             : 
     139             :   //! \name Constants
     140             :   //! \{
     141             : 
     142             :   enum : uint32_t {
     143             :     kNumBlockItems   = uint32_t((kBlockSize - sizeof(Block)) / sizeof(T)),
     144             :     kStartBlockIndex = uint32_t(sizeof(Block)),
     145             :     kMidBlockIndex   = uint32_t(kStartBlockIndex + (kNumBlockItems / 2) * sizeof(T)),
     146             :     kEndBlockIndex   = uint32_t(kStartBlockIndex + (kNumBlockItems    ) * sizeof(T))
     147             :   };
     148             : 
     149             :   //! \}
     150             : 
     151             :   //! \name Construction & Destruction
     152             :   //! \{
     153             : 
     154             :   inline ZoneStack() noexcept {}
     155       54984 :   inline ~ZoneStack() noexcept {}
     156             : 
     157       54984 :   inline Error init(ZoneAllocator* allocator) noexcept { return _init(allocator, kMidBlockIndex); }
     158             : 
     159             :   //! \}
     160             : 
     161             :   //! \name Utilities
     162             :   //! \{
     163             : 
     164             :   inline Error prepend(T item) noexcept {
     165             :     ASMJIT_ASSERT(isInitialized());
     166             :     Block* block = _block[kBlockIndexFirst];
     167             : 
     168             :     if (!block->canPrepend<T>()) {
     169             :       ASMJIT_PROPAGATE(_prepareBlock(kBlockIndexFirst, kEndBlockIndex));
     170             :       block = _block[kBlockIndexFirst];
     171             :     }
     172             : 
     173             :     T* ptr = block->start<T>() - 1;
     174             :     ASMJIT_ASSERT(ptr >= block->data<T>() && ptr <= block->data<T>() + (kNumBlockItems - 1));
     175             :     *ptr = item;
     176             :     block->setStart<T>(ptr);
     177             :     return kErrorOk;
     178             :   }
     179             : 
     180       82476 :   inline Error append(T item) noexcept {
     181             :     ASMJIT_ASSERT(isInitialized());
     182       82476 :     Block* block = _block[kBlockIndexLast];
     183             : 
     184       82476 :     if (!block->canAppend<T>()) {
     185           0 :       ASMJIT_PROPAGATE(_prepareBlock(kBlockIndexLast, kStartBlockIndex));
     186           0 :       block = _block[kBlockIndexLast];
     187             :     }
     188             : 
     189             :     T* ptr = block->end<T>();
     190             :     ASMJIT_ASSERT(ptr >= block->data<T>() && ptr <= block->data<T>() + (kNumBlockItems - 1));
     191             : 
     192       82476 :     *ptr++ = item;
     193             :     block->setEnd(ptr);
     194       82476 :     return kErrorOk;
     195             :   }
     196             : 
     197       54984 :   inline T popFirst() noexcept {
     198             :     ASMJIT_ASSERT(isInitialized());
     199             :     ASMJIT_ASSERT(!empty());
     200             : 
     201       54984 :     Block* block = _block[kBlockIndexFirst];
     202             :     ASMJIT_ASSERT(!block->empty());
     203             : 
     204             :     T* ptr = block->start<T>();
     205       54984 :     T item = *ptr++;
     206             : 
     207             :     block->setStart(ptr);
     208       54984 :     if (block->empty())
     209       27492 :       _cleanupBlock(kBlockIndexFirst, kMidBlockIndex);
     210             : 
     211       54984 :     return item;
     212             :   }
     213             : 
     214       27492 :   inline T pop() noexcept {
     215             :     ASMJIT_ASSERT(isInitialized());
     216             :     ASMJIT_ASSERT(!empty());
     217             : 
     218       27492 :     Block* block = _block[kBlockIndexLast];
     219             :     ASMJIT_ASSERT(!block->empty());
     220             : 
     221             :     T* ptr = block->end<T>();
     222       27492 :     T item = *--ptr;
     223             :     ASMJIT_ASSERT(ptr >= block->data<T>());
     224             :     ASMJIT_ASSERT(ptr >= block->start<T>());
     225             : 
     226             :     block->setEnd(ptr);
     227       27492 :     if (block->empty())
     228       27492 :       _cleanupBlock(kBlockIndexLast, kMidBlockIndex);
     229             : 
     230       27492 :     return item;
     231             :   }
     232             : 
     233             :   //! \}
     234             : };
     235             : 
     236             : //! \}
     237             : 
     238             : ASMJIT_END_NAMESPACE
     239             : 
     240             : #endif // ASMJIT_CORE_ZONESTACK_H_INCLUDED
     241             : 
     242             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16