LCOV - code coverage report
Current view: top level - asmjit - zonestack.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 25 39 64.1 %
Date: 2026-11-05 10:19:06 Functions: 2 3 66.7 %

          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             : #include "api-build_p.h"
       8             : #include "zone.h"
       9             : #include "zonestack.h"
      10             : 
      11             : ASMJIT_BEGIN_NAMESPACE
      12             : 
      13             : // ZoneStackBase - Init & Reset
      14             : // ============================
      15             : 
      16      137460 : Error ZoneStackBase::_init(ZoneAllocator* allocator, size_t middleIndex) noexcept {
      17      137460 :   ZoneAllocator* oldAllocator = _allocator;
      18             : 
      19      137460 :   if (oldAllocator) {
      20       54984 :     Block* block = _block[kBlockIndexFirst];
      21      109968 :     while (block) {
      22             :       Block* next = block->next();
      23             :       oldAllocator->release(block, kBlockSize);
      24             :       block = next;
      25             :     }
      26             : 
      27       54984 :     _allocator = nullptr;
      28       54984 :     _block[kBlockIndexFirst] = nullptr;
      29       54984 :     _block[kBlockIndexLast] = nullptr;
      30             :   }
      31             : 
      32      137460 :   if (allocator) {
      33             :     Block* block = static_cast<Block*>(allocator->alloc(kBlockSize));
      34       54984 :     if (ASMJIT_UNLIKELY(!block))
      35             :       return DebugUtils::errored(kErrorOutOfMemory);
      36             : 
      37       54984 :     block->_link[kBlockIndexPrev] = nullptr;
      38       54984 :     block->_link[kBlockIndexNext] = nullptr;
      39       54984 :     block->_start = (uint8_t*)block + middleIndex;
      40       54984 :     block->_end = (uint8_t*)block + middleIndex;
      41             : 
      42       54984 :     _allocator = allocator;
      43       54984 :     _block[kBlockIndexFirst] = block;
      44       54984 :     _block[kBlockIndexLast] = block;
      45             :   }
      46             : 
      47             :   return kErrorOk;
      48             : }
      49             : 
      50             : // ZoneStackBase - Operations
      51             : // ==========================
      52             : 
      53           0 : Error ZoneStackBase::_prepareBlock(uint32_t side, size_t initialIndex) noexcept {
      54             :   ASMJIT_ASSERT(isInitialized());
      55             : 
      56           0 :   Block* prev = _block[side];
      57             :   ASMJIT_ASSERT(!prev->empty());
      58             : 
      59           0 :   Block* block = _allocator->allocT<Block>(kBlockSize);
      60           0 :   if (ASMJIT_UNLIKELY(!block))
      61             :     return DebugUtils::errored(kErrorOutOfMemory);
      62             : 
      63           0 :   block->_link[ side] = nullptr;
      64           0 :   block->_link[!side] = prev;
      65           0 :   block->_start = (uint8_t*)block + initialIndex;
      66           0 :   block->_end = (uint8_t*)block + initialIndex;
      67             : 
      68           0 :   prev->_link[side] = block;
      69           0 :   _block[side] = block;
      70             : 
      71           0 :   return kErrorOk;
      72             : }
      73             : 
      74       54984 : void ZoneStackBase::_cleanupBlock(uint32_t side, size_t middleIndex) noexcept {
      75       54984 :   Block* block = _block[side];
      76             :   ASMJIT_ASSERT(block->empty());
      77             : 
      78       54984 :   Block* prev = block->_link[!side];
      79       54984 :   if (prev) {
      80             :     ASMJIT_ASSERT(prev->_link[side] == block);
      81           0 :     _allocator->release(block, kBlockSize);
      82             : 
      83           0 :     prev->_link[side] = nullptr;
      84           0 :     _block[side] = prev;
      85             :   }
      86       54984 :   else if (_block[!side] == block) {
      87             :     // If the container becomes empty center both pointers in the remaining block.
      88       54984 :     block->_start = (uint8_t*)block + middleIndex;
      89       54984 :     block->_end = (uint8_t*)block + middleIndex;
      90             :   }
      91       54984 : }
      92             : 
      93             : // ZoneStack - Tests
      94             : // =================
      95             : 
      96             : #if defined(ASMJIT_TEST)
      97             : template<typename T>
      98             : static void test_zone_stack(ZoneAllocator* allocator, const char* typeName) {
      99             :   ZoneStack<T> stack;
     100             : 
     101             :   INFO("Testing ZoneStack<%s>", typeName);
     102             :   INFO("  (%d items per one Block)", ZoneStack<T>::kNumBlockItems);
     103             : 
     104             :   EXPECT(stack.init(allocator) == kErrorOk);
     105             :   EXPECT(stack.empty(), "Stack must be empty after `init()`");
     106             : 
     107             :   EXPECT(stack.append(42) == kErrorOk);
     108             :   EXPECT(!stack.empty()        , "Stack must not be empty after an item has been appended");
     109             :   EXPECT(stack.pop() == 42     , "Stack.pop() must return the item that has been appended last");
     110             :   EXPECT(stack.empty()         , "Stack must be empty after the last item has been removed");
     111             : 
     112             :   EXPECT(stack.prepend(43) == kErrorOk);
     113             :   EXPECT(!stack.empty()        , "Stack must not be empty after an item has been prepended");
     114             :   EXPECT(stack.popFirst() == 43, "Stack.popFirst() must return the item that has been prepended last");
     115             :   EXPECT(stack.empty()         , "Stack must be empty after the last item has been removed");
     116             : 
     117             :   int i;
     118             :   int iMin =-100000;
     119             :   int iMax = 100000;
     120             : 
     121             :   INFO("Validating prepend() & popFirst()");
     122             :   for (i = iMax; i >= 0; i--) stack.prepend(T(i));
     123             :   for (i = 0; i <= iMax; i++) {
     124             :     T item = stack.popFirst();
     125             :     EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
     126             :     if (!stack.empty()) {
     127             :       item = stack.popFirst();
     128             :       EXPECT(i + 1 == item, "Item '%d' didn't match the item '%lld' popped", i + 1, (long long)item);
     129             :       stack.prepend(item);
     130             :     }
     131             :   }
     132             :   EXPECT(stack.empty());
     133             : 
     134             :   INFO("Validating append() & pop()");
     135             :   for (i = 0; i <= iMax; i++) stack.append(T(i));
     136             :   for (i = iMax; i >= 0; i--) {
     137             :     T item = stack.pop();
     138             :     EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
     139             :     if (!stack.empty()) {
     140             :       item = stack.pop();
     141             :       EXPECT(i - 1 == item, "Item '%d' didn't match the item '%lld' popped", i - 1, (long long)item);
     142             :       stack.append(item);
     143             :     }
     144             :   }
     145             :   EXPECT(stack.empty());
     146             : 
     147             :   INFO("Validating append()/prepend() & popFirst()");
     148             :   for (i = 1; i <= iMax; i++) stack.append(T(i));
     149             :   for (i = 0; i >= iMin; i--) stack.prepend(T(i));
     150             : 
     151             :   for (i = iMin; i <= iMax; i++) {
     152             :     T item = stack.popFirst();
     153             :     EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
     154             :   }
     155             :   EXPECT(stack.empty());
     156             : 
     157             :   INFO("Validating append()/prepend() & pop()");
     158             :   for (i = 0; i >= iMin; i--) stack.prepend(T(i));
     159             :   for (i = 1; i <= iMax; i++) stack.append(T(i));
     160             : 
     161             :   for (i = iMax; i >= iMin; i--) {
     162             :     T item = stack.pop();
     163             :     EXPECT(i == item, "Item '%d' didn't match the item '%lld' popped", i, (long long)item);
     164             :   }
     165             :   EXPECT(stack.empty());
     166             : }
     167             : 
     168             : UNIT(zone_stack) {
     169             :   Zone zone(8096 - Zone::kBlockOverhead);
     170             :   ZoneAllocator allocator(&zone);
     171             : 
     172             :   test_zone_stack<int>(&allocator, "int");
     173             :   test_zone_stack<int64_t>(&allocator, "int64_t");
     174             : }
     175             : #endif
     176             : 
     177             : ASMJIT_END_NAMESPACE
     178             : 
     179             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16