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