Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===------ ExecutorAddress.h - Executing process address -------*- 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. // Represents an address in the executing program.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  14. #define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  15.  
  16. #include "llvm/ADT/DenseMapInfo.h"
  17. #include "llvm/ADT/identity.h"
  18. #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
  19. #include "llvm/Support/FormatVariadic.h"
  20. #include "llvm/Support/raw_ostream.h"
  21.  
  22. #include <cassert>
  23. #include <type_traits>
  24.  
  25. namespace llvm {
  26. namespace orc {
  27.  
  28. using ExecutorAddrDiff = uint64_t;
  29.  
  30. /// Represents an address in the executor process.
  31. class ExecutorAddr {
  32. public:
  33.   /// A wrap/unwrap function that leaves pointers unmodified.
  34.   template <typename T> using rawPtr = llvm::identity<T *>;
  35.  
  36.   /// Default wrap function to use on this host.
  37.   template <typename T> using defaultWrap = rawPtr<T>;
  38.  
  39.   /// Default unwrap function to use on this host.
  40.   template <typename T> using defaultUnwrap = rawPtr<T>;
  41.  
  42.   /// Merges a tag into the raw address value:
  43.   ///   P' = P | (TagValue << TagOffset).
  44.   class Tag {
  45.   public:
  46.     constexpr Tag(uintptr_t TagValue, uintptr_t TagOffset)
  47.         : TagMask(TagValue << TagOffset) {}
  48.  
  49.     template <typename T> constexpr T *operator()(T *P) {
  50.       return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) | TagMask);
  51.     }
  52.  
  53.   private:
  54.     uintptr_t TagMask;
  55.   };
  56.  
  57.   /// Strips a tag of the given length from the given offset within the pointer:
  58.   /// P' = P & ~(((1 << TagLen) -1) << TagOffset)
  59.   class Untag {
  60.   public:
  61.     constexpr Untag(uintptr_t TagLen, uintptr_t TagOffset)
  62.         : UntagMask(~(((uintptr_t(1) << TagLen) - 1) << TagOffset)) {}
  63.  
  64.     template <typename T> constexpr T *operator()(T *P) {
  65.       return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(P) & UntagMask);
  66.     }
  67.  
  68.   private:
  69.     uintptr_t UntagMask;
  70.   };
  71.  
  72.   ExecutorAddr() = default;
  73.  
  74.   /// Create an ExecutorAddr from the given value.
  75.   explicit constexpr ExecutorAddr(uint64_t Addr) : Addr(Addr) {}
  76.  
  77.   /// Create an ExecutorAddr from the given pointer.
  78.   /// Warning: This should only be used when JITing in-process.
  79.   template <typename T, typename UnwrapFn = defaultUnwrap<T>>
  80.   static ExecutorAddr fromPtr(T *Ptr, UnwrapFn &&Unwrap = UnwrapFn()) {
  81.     return ExecutorAddr(
  82.         static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Unwrap(Ptr))));
  83.   }
  84.  
  85.   /// Cast this ExecutorAddr to a pointer of the given type.
  86.   /// Warning: This should only be used when JITing in-process.
  87.   template <typename T, typename WrapFn = defaultWrap<std::remove_pointer_t<T>>>
  88.   std::enable_if_t<std::is_pointer<T>::value, T>
  89.   toPtr(WrapFn &&Wrap = WrapFn()) const {
  90.     uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
  91.     assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
  92.     return Wrap(reinterpret_cast<T>(IntPtr));
  93.   }
  94.  
  95.   /// Cast this ExecutorAddr to a pointer of the given function type.
  96.   /// Warning: This should only be used when JITing in-process.
  97.   template <typename T, typename WrapFn = defaultWrap<T>>
  98.   std::enable_if_t<std::is_function<T>::value, T *>
  99.   toPtr(WrapFn &&Wrap = WrapFn()) const {
  100.     uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
  101.     assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
  102.     return Wrap(reinterpret_cast<T *>(IntPtr));
  103.   }
  104.  
  105.   uint64_t getValue() const { return Addr; }
  106.   void setValue(uint64_t Addr) { this->Addr = Addr; }
  107.   bool isNull() const { return Addr == 0; }
  108.  
  109.   explicit operator bool() const { return Addr != 0; }
  110.  
  111.   friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  112.     return LHS.Addr == RHS.Addr;
  113.   }
  114.  
  115.   friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  116.     return LHS.Addr != RHS.Addr;
  117.   }
  118.  
  119.   friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  120.     return LHS.Addr < RHS.Addr;
  121.   }
  122.  
  123.   friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  124.     return LHS.Addr <= RHS.Addr;
  125.   }
  126.  
  127.   friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  128.     return LHS.Addr > RHS.Addr;
  129.   }
  130.  
  131.   friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  132.     return LHS.Addr >= RHS.Addr;
  133.   }
  134.  
  135.   ExecutorAddr &operator++() {
  136.     ++Addr;
  137.     return *this;
  138.   }
  139.   ExecutorAddr &operator--() {
  140.     --Addr;
  141.     return *this;
  142.   }
  143.   ExecutorAddr operator++(int) { return ExecutorAddr(Addr++); }
  144.   ExecutorAddr operator--(int) { return ExecutorAddr(Addr--); }
  145.  
  146.   ExecutorAddr &operator+=(const ExecutorAddrDiff &Delta) {
  147.     Addr += Delta;
  148.     return *this;
  149.   }
  150.  
  151.   ExecutorAddr &operator-=(const ExecutorAddrDiff &Delta) {
  152.     Addr -= Delta;
  153.     return *this;
  154.   }
  155.  
  156. private:
  157.   uint64_t Addr = 0;
  158. };
  159.  
  160. /// Subtracting two addresses yields an offset.
  161. inline ExecutorAddrDiff operator-(const ExecutorAddr &LHS,
  162.                                   const ExecutorAddr &RHS) {
  163.   return ExecutorAddrDiff(LHS.getValue() - RHS.getValue());
  164. }
  165.  
  166. /// Adding an offset and an address yields an address.
  167. inline ExecutorAddr operator+(const ExecutorAddr &LHS,
  168.                               const ExecutorAddrDiff &RHS) {
  169.   return ExecutorAddr(LHS.getValue() + RHS);
  170. }
  171.  
  172. /// Adding an address and an offset yields an address.
  173. inline ExecutorAddr operator+(const ExecutorAddrDiff &LHS,
  174.                               const ExecutorAddr &RHS) {
  175.   return ExecutorAddr(LHS + RHS.getValue());
  176. }
  177.  
  178. /// Subtracting an offset from an address yields an address.
  179. inline ExecutorAddr operator-(const ExecutorAddr &LHS,
  180.                               const ExecutorAddrDiff &RHS) {
  181.   return ExecutorAddr(LHS.getValue() - RHS);
  182. }
  183.  
  184. /// Taking the modulus of an address and a diff yields a diff.
  185. inline ExecutorAddrDiff operator%(const ExecutorAddr &LHS,
  186.                                   const ExecutorAddrDiff &RHS) {
  187.   return ExecutorAddrDiff(LHS.getValue() % RHS);
  188. }
  189.  
  190. /// Represents an address range in the exceutor process.
  191. struct ExecutorAddrRange {
  192.   ExecutorAddrRange() = default;
  193.   ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End)
  194.       : Start(Start), End(End) {}
  195.   ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size)
  196.       : Start(Start), End(Start + Size) {}
  197.  
  198.   bool empty() const { return Start == End; }
  199.   ExecutorAddrDiff size() const { return End - Start; }
  200.  
  201.   friend bool operator==(const ExecutorAddrRange &LHS,
  202.                          const ExecutorAddrRange &RHS) {
  203.     return LHS.Start == RHS.Start && LHS.End == RHS.End;
  204.   }
  205.   friend bool operator!=(const ExecutorAddrRange &LHS,
  206.                          const ExecutorAddrRange &RHS) {
  207.     return !(LHS == RHS);
  208.   }
  209.   bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; }
  210.   bool overlaps(const ExecutorAddrRange &Other) {
  211.     return !(Other.End <= Start || End <= Other.Start);
  212.   }
  213.  
  214.   ExecutorAddr Start;
  215.   ExecutorAddr End;
  216. };
  217.  
  218. inline raw_ostream &operator<<(raw_ostream &OS, const ExecutorAddr &A) {
  219.   return OS << formatv("{0:x}", A.getValue());
  220. }
  221.  
  222. inline raw_ostream &operator<<(raw_ostream &OS, const ExecutorAddrRange &R) {
  223.   return OS << formatv("{0:x} -- {1:x}", R.Start.getValue(), R.End.getValue());
  224. }
  225.  
  226. namespace shared {
  227.  
  228. class SPSExecutorAddr {};
  229.  
  230. /// SPS serializatior for ExecutorAddr.
  231. template <> class SPSSerializationTraits<SPSExecutorAddr, ExecutorAddr> {
  232. public:
  233.   static size_t size(const ExecutorAddr &EA) {
  234.     return SPSArgList<uint64_t>::size(EA.getValue());
  235.   }
  236.  
  237.   static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA) {
  238.     return SPSArgList<uint64_t>::serialize(BOB, EA.getValue());
  239.   }
  240.  
  241.   static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA) {
  242.     uint64_t Tmp;
  243.     if (!SPSArgList<uint64_t>::deserialize(BIB, Tmp))
  244.       return false;
  245.     EA = ExecutorAddr(Tmp);
  246.     return true;
  247.   }
  248. };
  249.  
  250. using SPSExecutorAddrRange = SPSTuple<SPSExecutorAddr, SPSExecutorAddr>;
  251.  
  252. /// Serialization traits for address ranges.
  253. template <>
  254. class SPSSerializationTraits<SPSExecutorAddrRange, ExecutorAddrRange> {
  255. public:
  256.   static size_t size(const ExecutorAddrRange &Value) {
  257.     return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::size(Value.Start,
  258.                                                               Value.End);
  259.   }
  260.  
  261.   static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value) {
  262.     return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::serialize(
  263.         BOB, Value.Start, Value.End);
  264.   }
  265.  
  266.   static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value) {
  267.     return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::deserialize(
  268.         BIB, Value.Start, Value.End);
  269.   }
  270. };
  271.  
  272. using SPSExecutorAddrRangeSequence = SPSSequence<SPSExecutorAddrRange>;
  273.  
  274. } // End namespace shared.
  275. } // End namespace orc.
  276.  
  277. // Provide DenseMapInfo for ExecutorAddrs.
  278. template <> struct DenseMapInfo<orc::ExecutorAddr> {
  279.   static inline orc::ExecutorAddr getEmptyKey() {
  280.     return orc::ExecutorAddr(DenseMapInfo<uint64_t>::getEmptyKey());
  281.   }
  282.   static inline orc::ExecutorAddr getTombstoneKey() {
  283.     return orc::ExecutorAddr(DenseMapInfo<uint64_t>::getTombstoneKey());
  284.   }
  285.  
  286.   static unsigned getHashValue(const orc::ExecutorAddr &Addr) {
  287.     return DenseMapInfo<uint64_t>::getHashValue(Addr.getValue());
  288.   }
  289.  
  290.   static bool isEqual(const orc::ExecutorAddr &LHS,
  291.                       const orc::ExecutorAddr &RHS) {
  292.     return DenseMapInfo<uint64_t>::isEqual(LHS.getValue(), RHS.getValue());
  293.   }
  294. };
  295.  
  296. } // End namespace llvm.
  297.  
  298. #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  299.