Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===-------- MemoryFlags.h - Memory allocation flags -----------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Defines types and operations related to memory protection and allocation
  10. // lifetimes.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
  15. #define LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
  16.  
  17. #include "llvm/ADT/BitmaskEnum.h"
  18. #include "llvm/ADT/DenseMapInfo.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/Support/Memory.h"
  21. #include "llvm/Support/raw_ostream.h"
  22.  
  23. namespace llvm {
  24. namespace orc {
  25.  
  26. /// Describes Read/Write/Exec permissions for memory.
  27. enum class MemProt {
  28.   None = 0,
  29.   Read = 1U << 0,
  30.   Write = 1U << 1,
  31.   Exec = 1U << 2,
  32.   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Exec)
  33. };
  34.  
  35. /// Print a MemProt as an RWX triple.
  36. inline raw_ostream &operator<<(raw_ostream &OS, MemProt MP) {
  37.   return OS << (((MP & MemProt::Read) != MemProt::None) ? 'R' : '-')
  38.             << (((MP & MemProt::Write) != MemProt::None) ? 'W' : '-')
  39.             << (((MP & MemProt::Exec) != MemProt::None) ? 'X' : '-');
  40. }
  41.  
  42. /// Convert a MemProt value to a corresponding sys::Memory::ProtectionFlags
  43. /// value.
  44. inline sys::Memory::ProtectionFlags toSysMemoryProtectionFlags(MemProt MP) {
  45.   std::underlying_type_t<sys::Memory::ProtectionFlags> PF = 0;
  46.   if ((MP & MemProt::Read) != MemProt::None)
  47.     PF |= sys::Memory::MF_READ;
  48.   if ((MP & MemProt::Write) != MemProt::None)
  49.     PF |= sys::Memory::MF_WRITE;
  50.   if ((MP & MemProt::Exec) != MemProt::None)
  51.     PF |= sys::Memory::MF_EXEC;
  52.   return static_cast<sys::Memory::ProtectionFlags>(PF);
  53. }
  54.  
  55. /// Convert a sys::Memory::ProtectionFlags value to a corresponding MemProt
  56. /// value.
  57. inline MemProt fromSysMemoryProtectionFlags(sys::Memory::ProtectionFlags PF) {
  58.   MemProt MP = MemProt::None;
  59.   if (PF & sys::Memory::MF_READ)
  60.     MP |= MemProt::Read;
  61.   if (PF & sys::Memory::MF_WRITE)
  62.     MP |= MemProt::Write;
  63.   if (PF & sys::Memory::MF_EXEC)
  64.     MP |= MemProt::None;
  65.   return MP;
  66. }
  67.  
  68. /// Describes a memory deallocation policy for memory to be allocated by a
  69. /// JITLinkMemoryManager.
  70. ///
  71. /// All memory allocated by a call to JITLinkMemoryManager::allocate should be
  72. /// deallocated if a call is made to
  73. /// JITLinkMemoryManager::InFlightAllocation::abandon. The policies below apply
  74. /// to finalized allocations.
  75. enum class MemDeallocPolicy {
  76.   /// Standard memory should be deallocated when the deallocate method is called
  77.   /// for the finalized allocation.
  78.   Standard,
  79.  
  80.   /// Finalize memory should be overwritten and then deallocated after all
  81.   /// finalization functions have been run.
  82.   Finalize
  83. };
  84.  
  85. /// Print a MemDeallocPolicy.
  86. inline raw_ostream &operator<<(raw_ostream &OS, MemDeallocPolicy MDP) {
  87.   return OS << (MDP == MemDeallocPolicy::Standard ? "standard" : "finalize");
  88. }
  89.  
  90. /// A pair of memory protections and allocation policies.
  91. ///
  92. /// Optimized for use as a small map key.
  93. class AllocGroup {
  94.   friend struct llvm::DenseMapInfo<AllocGroup>;
  95.  
  96.   using underlying_type = uint8_t;
  97.   static constexpr unsigned BitsForProt = 3;
  98.   static constexpr unsigned BitsForDeallocPolicy = 1;
  99.   static constexpr unsigned MaxIdentifiers =
  100.       1U << (BitsForProt + BitsForDeallocPolicy);
  101.  
  102. public:
  103.   static constexpr unsigned NumGroups = MaxIdentifiers;
  104.  
  105.   /// Create a default AllocGroup. No memory protections, standard
  106.   /// deallocation policy.
  107.   AllocGroup() = default;
  108.  
  109.   /// Create an AllocGroup from a MemProt only -- uses
  110.   /// MemoryDeallocationPolicy::Standard.
  111.   AllocGroup(MemProt MP) : Id(static_cast<underlying_type>(MP)) {}
  112.  
  113.   /// Create an AllocGroup from a MemProt and a MemoryDeallocationPolicy.
  114.   AllocGroup(MemProt MP, MemDeallocPolicy MDP)
  115.       : Id(static_cast<underlying_type>(MP) |
  116.            (static_cast<underlying_type>(MDP) << BitsForProt)) {}
  117.  
  118.   /// Returns the MemProt for this group.
  119.   MemProt getMemProt() const {
  120.     return static_cast<MemProt>(Id & ((1U << BitsForProt) - 1));
  121.   }
  122.  
  123.   /// Returns the MemoryDeallocationPolicy for this group.
  124.   MemDeallocPolicy getMemDeallocPolicy() const {
  125.     return static_cast<MemDeallocPolicy>(Id >> BitsForProt);
  126.   }
  127.  
  128.   friend bool operator==(const AllocGroup &LHS, const AllocGroup &RHS) {
  129.     return LHS.Id == RHS.Id;
  130.   }
  131.  
  132.   friend bool operator!=(const AllocGroup &LHS, const AllocGroup &RHS) {
  133.     return !(LHS == RHS);
  134.   }
  135.  
  136.   friend bool operator<(const AllocGroup &LHS, const AllocGroup &RHS) {
  137.     return LHS.Id < RHS.Id;
  138.   }
  139.  
  140. private:
  141.   AllocGroup(underlying_type RawId) : Id(RawId) {}
  142.   underlying_type Id = 0;
  143. };
  144.  
  145. /// A specialized small-map for AllocGroups.
  146. ///
  147. /// Iteration order is guaranteed to match key ordering.
  148. template <typename T> class AllocGroupSmallMap {
  149. private:
  150.   using ElemT = std::pair<AllocGroup, T>;
  151.   using VectorTy = SmallVector<ElemT, 4>;
  152.  
  153.   static bool compareKey(const ElemT &E, const AllocGroup &G) {
  154.     return E.first < G;
  155.   }
  156.  
  157. public:
  158.   using iterator = typename VectorTy::iterator;
  159.  
  160.   AllocGroupSmallMap() = default;
  161.   AllocGroupSmallMap(std::initializer_list<std::pair<AllocGroup, T>> Inits)
  162.       : Elems(Inits) {
  163.     llvm::sort(Elems, llvm::less_first());
  164.   }
  165.  
  166.   iterator begin() { return Elems.begin(); }
  167.   iterator end() { return Elems.end(); }
  168.   iterator find(AllocGroup G) {
  169.     auto I = lower_bound(Elems, G, compareKey);
  170.     return (I->first == G) ? I : end();
  171.   }
  172.  
  173.   bool empty() const { return Elems.empty(); }
  174.   size_t size() const { return Elems.size(); }
  175.  
  176.   T &operator[](AllocGroup G) {
  177.     auto I = lower_bound(Elems, G, compareKey);
  178.     if (I == Elems.end() || I->first != G)
  179.       I = Elems.insert(I, std::make_pair(G, T()));
  180.     return I->second;
  181.   }
  182.  
  183. private:
  184.   VectorTy Elems;
  185. };
  186.  
  187. /// Print an AllocGroup.
  188. inline raw_ostream &operator<<(raw_ostream &OS, AllocGroup AG) {
  189.   return OS << '(' << AG.getMemProt() << ", " << AG.getMemDeallocPolicy()
  190.             << ')';
  191. }
  192.  
  193. } // end namespace orc
  194.  
  195. template <> struct DenseMapInfo<orc::MemProt> {
  196.   static inline orc::MemProt getEmptyKey() { return orc::MemProt(~uint8_t(0)); }
  197.   static inline orc::MemProt getTombstoneKey() {
  198.     return orc::MemProt(~uint8_t(0) - 1);
  199.   }
  200.   static unsigned getHashValue(const orc::MemProt &Val) {
  201.     using UT = std::underlying_type_t<orc::MemProt>;
  202.     return DenseMapInfo<UT>::getHashValue(static_cast<UT>(Val));
  203.   }
  204.   static bool isEqual(const orc::MemProt &LHS, const orc::MemProt &RHS) {
  205.     return LHS == RHS;
  206.   }
  207. };
  208.  
  209. template <> struct DenseMapInfo<orc::AllocGroup> {
  210.   static inline orc::AllocGroup getEmptyKey() {
  211.     return orc::AllocGroup(~uint8_t(0));
  212.   }
  213.   static inline orc::AllocGroup getTombstoneKey() {
  214.     return orc::AllocGroup(~uint8_t(0) - 1);
  215.   }
  216.   static unsigned getHashValue(const orc::AllocGroup &Val) {
  217.     return DenseMapInfo<orc::AllocGroup::underlying_type>::getHashValue(Val.Id);
  218.   }
  219.   static bool isEqual(const orc::AllocGroup &LHS, const orc::AllocGroup &RHS) {
  220.     return LHS == RHS;
  221.   }
  222. };
  223.  
  224. } // end namespace llvm
  225.  
  226. #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_MEMORYFLAGS_H
  227.