LCOV - code coverage report
Current view: top level - asmjit - constpool.h (source / functions) Hit Total Coverage
Test: plumed test coverage (other modules) Lines: 0 35 0.0 %
Date: 2026-11-05 10:19:06 Functions: 0 3 0.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_CONSTPOOL_H_INCLUDED
       8             : #define ASMJIT_CORE_CONSTPOOL_H_INCLUDED
       9             : 
      10             : #include "support.h"
      11             : #include "zone.h"
      12             : #include "zonetree.h"
      13             : 
      14             : ASMJIT_BEGIN_NAMESPACE
      15             : 
      16             : //! \addtogroup asmjit_utilities
      17             : //! \{
      18             : 
      19             : //! Constant pool scope.
      20             : enum class ConstPoolScope : uint32_t {
      21             :   //! Local constant, always embedded right after the current function.
      22             :   kLocal = 0,
      23             :   //! Global constant, embedded at the end of the currently compiled code.
      24             :   kGlobal = 1,
      25             : 
      26             :   //! Maximum value of `ConstPoolScope`.
      27             :   kMaxValue = kGlobal
      28             : };
      29             : 
      30             : //! Constant pool.
      31             : class ConstPool {
      32             : public:
      33             :   ASMJIT_NONCOPYABLE(ConstPool)
      34             : 
      35             :   //! \cond INTERNAL
      36             : 
      37             :   //! Index of a given size in const-pool table.
      38             :   enum Index : uint32_t {
      39             :     kIndex1 = 0,
      40             :     kIndex2 = 1,
      41             :     kIndex4 = 2,
      42             :     kIndex8 = 3,
      43             :     kIndex16 = 4,
      44             :     kIndex32 = 5,
      45             :     kIndex64 = 6,
      46             :     kIndexCount = 7
      47             :   };
      48             : 
      49             :   //! Zone-allocated const-pool gap created by two differently aligned constants.
      50             :   struct Gap {
      51             :     //! Pointer to the next gap
      52             :     Gap* _next;
      53             :     //! Offset of the gap.
      54             :     size_t _offset;
      55             :     //! Remaining bytes of the gap (basically a gap size).
      56             :     size_t _size;
      57             :   };
      58             : 
      59             :   //! Zone-allocated const-pool node.
      60             :   class Node : public ZoneTreeNodeT<Node> {
      61             :   public:
      62             :     ASMJIT_NONCOPYABLE(Node)
      63             : 
      64             :     //! If this constant is shared with another.
      65             :     uint32_t _shared : 1;
      66             :     //! Data offset from the beginning of the pool.
      67             :     uint32_t _offset;
      68             : 
      69             :     inline Node(size_t offset, bool shared) noexcept
      70           0 :       : ZoneTreeNodeT<Node>(),
      71           0 :         _shared(shared),
      72           0 :         _offset(uint32_t(offset)) {}
      73             : 
      74             :     inline void* data() const noexcept {
      75           0 :       return static_cast<void*>(const_cast<ConstPool::Node*>(this) + 1);
      76             :     }
      77             :   };
      78             : 
      79             :   //! Data comparer used internally.
      80             :   class Compare {
      81             :   public:
      82             :     size_t _dataSize;
      83             : 
      84             :     inline Compare(size_t dataSize) noexcept
      85           0 :       : _dataSize(dataSize) {}
      86             : 
      87             :     inline int operator()(const Node& a, const Node& b) const noexcept {
      88           0 :       return ::memcmp(a.data(), b.data(), _dataSize);
      89             :     }
      90             : 
      91             :     inline int operator()(const Node& a, const void* data) const noexcept {
      92           0 :       return ::memcmp(a.data(), data, _dataSize);
      93             :     }
      94             :   };
      95             : 
      96             :   //! Zone-allocated const-pool tree.
      97             :   struct Tree {
      98             :     //! RB tree.
      99             :     ZoneTree<Node> _tree;
     100             :     //! Size of the tree (number of nodes).
     101             :     size_t _size;
     102             :     //! Size of the data.
     103             :     size_t _dataSize;
     104             : 
     105             :     inline explicit Tree(size_t dataSize = 0) noexcept
     106           0 :       : _tree(),
     107           0 :         _size(0),
     108           0 :         _dataSize(dataSize) {}
     109             : 
     110             :     inline void reset() noexcept {
     111             :       _tree.reset();
     112           0 :       _size = 0;
     113             :     }
     114             : 
     115             :     inline bool empty() const noexcept { return _size == 0; }
     116             :     inline size_t size() const noexcept { return _size; }
     117             : 
     118             :     inline void setDataSize(size_t dataSize) noexcept {
     119             :       ASMJIT_ASSERT(empty());
     120           0 :       _dataSize = dataSize;
     121             :     }
     122             : 
     123             :     inline Node* get(const void* data) noexcept {
     124           0 :       Compare cmp(_dataSize);
     125           0 :       return _tree.get(data, cmp);
     126             :     }
     127             : 
     128           0 :     inline void insert(Node* node) noexcept {
     129           0 :       Compare cmp(_dataSize);
     130           0 :       _tree.insert(node, cmp);
     131           0 :       _size++;
     132           0 :     }
     133             : 
     134             :     template<typename Visitor>
     135           0 :     inline void forEach(Visitor& visitor) const noexcept {
     136             :       Node* node = _tree.root();
     137           0 :       if (!node) return;
     138             : 
     139             :       Node* stack[Globals::kMaxTreeHeight];
     140             :       size_t top = 0;
     141             : 
     142             :       for (;;) {
     143             :         Node* left = node->left();
     144           0 :         if (left != nullptr) {
     145             :           ASMJIT_ASSERT(top != Globals::kMaxTreeHeight);
     146           0 :           stack[top++] = node;
     147             : 
     148             :           node = left;
     149           0 :           continue;
     150             :         }
     151             : 
     152             :         for (;;) {
     153           0 :           visitor(node);
     154             :           node = node->right();
     155             : 
     156           0 :           if (node != nullptr)
     157             :             break;
     158             : 
     159           0 :           if (top == 0)
     160             :             return;
     161             : 
     162           0 :           node = stack[--top];
     163             :         }
     164             :       }
     165             :     }
     166             : 
     167           0 :     static inline Node* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) noexcept {
     168           0 :       Node* node = zone->allocT<Node>(sizeof(Node) + size);
     169           0 :       if (ASMJIT_UNLIKELY(!node)) return nullptr;
     170             : 
     171             :       node = new(node) Node(offset, shared);
     172             :       memcpy(node->data(), data, size);
     173           0 :       return node;
     174             :     }
     175             :   };
     176             : 
     177             :   //! \endcond
     178             : 
     179             :   //! \name Members
     180             :   //! \{
     181             : 
     182             :   //! Zone allocator.
     183             :   Zone* _zone;
     184             :   //! Tree per size.
     185             :   Tree _tree[kIndexCount];
     186             :   //! Gaps per size.
     187             :   Gap* _gaps[kIndexCount];
     188             :   //! Gaps pool
     189             :   Gap* _gapPool;
     190             : 
     191             :   //! Size of the pool (in bytes).
     192             :   size_t _size;
     193             :   //! Required pool alignment.
     194             :   size_t _alignment;
     195             :   //! Minimum item size in the pool.
     196             :   size_t _minItemSize;
     197             : 
     198             :   //! \}
     199             : 
     200             :   //! \name Construction & Destruction
     201             :   //! \{
     202             : 
     203             :   ASMJIT_API ConstPool(Zone* zone) noexcept;
     204             :   ASMJIT_API ~ConstPool() noexcept;
     205             : 
     206             :   ASMJIT_API void reset(Zone* zone) noexcept;
     207             : 
     208             :   //! \}
     209             : 
     210             :   //! \name Accessors
     211             :   //! \{
     212             : 
     213             :   //! Tests whether the constant-pool is empty.
     214             :   inline bool empty() const noexcept { return _size == 0; }
     215             :   //! Returns the size of the constant-pool in bytes.
     216           0 :   inline size_t size() const noexcept { return _size; }
     217             :   //! Returns minimum alignment.
     218           0 :   inline size_t alignment() const noexcept { return _alignment; }
     219             :   //! Returns the minimum size of all items added to the constant pool.
     220           0 :   inline size_t minItemSize() const noexcept { return _minItemSize; }
     221             : 
     222             :   //! \}
     223             : 
     224             :   //! \name Utilities
     225             :   //! \{
     226             : 
     227             :   //! Adds a constant to the constant pool.
     228             :   //!
     229             :   //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes. The constant is added to the pool only
     230             :   //! if it doesn't not exist, otherwise cached value is returned.
     231             :   //!
     232             :   //! AsmJit is able to subdivide added constants, so for example if you add 8-byte constant 0x1122334455667788 it
     233             :   //! will create the following slots:
     234             :   //!
     235             :   //!   8-byte: 0x1122334455667788
     236             :   //!   4-byte: 0x11223344, 0x55667788
     237             :   //!
     238             :   //! The reason is that when combining MMX/SSE/AVX code some patterns are used frequently. However, AsmJit is not
     239             :   //! able to reallocate a constant that has been already added. For example if you try to add 4-byte constant and
     240             :   //! then 8-byte constant having the same 4-byte pattern as the previous one, two independent slots will be used.
     241             :   ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset) noexcept;
     242             : 
     243             :   //! Fills the destination with the content of this constant pool.
     244             :   ASMJIT_API void fill(void* dst) const noexcept;
     245             : };
     246             : 
     247             : //! \}
     248             : 
     249             : ASMJIT_END_NAMESPACE
     250             : 
     251             : #endif // ASMJIT_CORE_CONSTPOOL_H_INCLUDED
     252             : 
     253             : #endif // __PLUMED_HAS_ASMJIT

Generated by: LCOV version 1.16