ExecutorAddress.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===------ ExecutorAddress.h - Executing process address -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Represents an address in the executing program.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  18. #define LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  19. #include "llvm/ADT/DenseMapInfo.h"
  20. #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
  21. #include "llvm/Support/FormatVariadic.h"
  22. #include "llvm/Support/raw_ostream.h"
  23. #include <cassert>
  24. #include <type_traits>
  25. namespace llvm {
  26. namespace orc {
  27. using ExecutorAddrDiff = uint64_t;
  28. /// Represents an address in the executor process.
  29. class ExecutorAddr {
  30. public:
  31. ExecutorAddr() = default;
  32. /// Create an ExecutorAddr from the given value.
  33. explicit constexpr ExecutorAddr(uint64_t Addr) : Addr(Addr) {}
  34. /// Create an ExecutorAddr from the given pointer.
  35. /// Warning: This should only be used when JITing in-process.
  36. template <typename T> static ExecutorAddr fromPtr(T *Value) {
  37. return ExecutorAddr(
  38. static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Value)));
  39. }
  40. /// Cast this ExecutorAddr to a pointer of the given type.
  41. /// Warning: This should only be used when JITing in-process.
  42. template <typename T> T toPtr() const {
  43. static_assert(std::is_pointer<T>::value, "T must be a pointer type");
  44. uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
  45. assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
  46. return reinterpret_cast<T>(IntPtr);
  47. }
  48. uint64_t getValue() const { return Addr; }
  49. void setValue(uint64_t Addr) { this->Addr = Addr; }
  50. bool isNull() const { return Addr == 0; }
  51. explicit operator bool() const { return Addr != 0; }
  52. friend bool operator==(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  53. return LHS.Addr == RHS.Addr;
  54. }
  55. friend bool operator!=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  56. return LHS.Addr != RHS.Addr;
  57. }
  58. friend bool operator<(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  59. return LHS.Addr < RHS.Addr;
  60. }
  61. friend bool operator<=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  62. return LHS.Addr <= RHS.Addr;
  63. }
  64. friend bool operator>(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  65. return LHS.Addr > RHS.Addr;
  66. }
  67. friend bool operator>=(const ExecutorAddr &LHS, const ExecutorAddr &RHS) {
  68. return LHS.Addr >= RHS.Addr;
  69. }
  70. ExecutorAddr &operator++() {
  71. ++Addr;
  72. return *this;
  73. }
  74. ExecutorAddr &operator--() {
  75. --Addr;
  76. return *this;
  77. }
  78. ExecutorAddr operator++(int) { return ExecutorAddr(Addr++); }
  79. ExecutorAddr operator--(int) { return ExecutorAddr(Addr--); }
  80. ExecutorAddr &operator+=(const ExecutorAddrDiff &Delta) {
  81. Addr += Delta;
  82. return *this;
  83. }
  84. ExecutorAddr &operator-=(const ExecutorAddrDiff &Delta) {
  85. Addr -= Delta;
  86. return *this;
  87. }
  88. private:
  89. uint64_t Addr = 0;
  90. };
  91. /// Subtracting two addresses yields an offset.
  92. inline ExecutorAddrDiff operator-(const ExecutorAddr &LHS,
  93. const ExecutorAddr &RHS) {
  94. return ExecutorAddrDiff(LHS.getValue() - RHS.getValue());
  95. }
  96. /// Adding an offset and an address yields an address.
  97. inline ExecutorAddr operator+(const ExecutorAddr &LHS,
  98. const ExecutorAddrDiff &RHS) {
  99. return ExecutorAddr(LHS.getValue() + RHS);
  100. }
  101. /// Adding an address and an offset yields an address.
  102. inline ExecutorAddr operator+(const ExecutorAddrDiff &LHS,
  103. const ExecutorAddr &RHS) {
  104. return ExecutorAddr(LHS + RHS.getValue());
  105. }
  106. /// Subtracting an offset from an address yields an address.
  107. inline ExecutorAddr operator-(const ExecutorAddr &LHS,
  108. const ExecutorAddrDiff &RHS) {
  109. return ExecutorAddr(LHS.getValue() - RHS);
  110. }
  111. /// Taking the modulus of an address and a diff yields a diff.
  112. inline ExecutorAddrDiff operator%(const ExecutorAddr &LHS,
  113. const ExecutorAddrDiff &RHS) {
  114. return ExecutorAddrDiff(LHS.getValue() % RHS);
  115. }
  116. /// Represents an address range in the exceutor process.
  117. struct ExecutorAddrRange {
  118. ExecutorAddrRange() = default;
  119. ExecutorAddrRange(ExecutorAddr Start, ExecutorAddr End)
  120. : Start(Start), End(End) {}
  121. ExecutorAddrRange(ExecutorAddr Start, ExecutorAddrDiff Size)
  122. : Start(Start), End(Start + Size) {}
  123. bool empty() const { return Start == End; }
  124. ExecutorAddrDiff size() const { return End - Start; }
  125. friend bool operator==(const ExecutorAddrRange &LHS,
  126. const ExecutorAddrRange &RHS) {
  127. return LHS.Start == RHS.Start && LHS.End == RHS.End;
  128. }
  129. friend bool operator!=(const ExecutorAddrRange &LHS,
  130. const ExecutorAddrRange &RHS) {
  131. return !(LHS == RHS);
  132. }
  133. bool contains(ExecutorAddr Addr) const { return Start <= Addr && Addr < End; }
  134. bool overlaps(const ExecutorAddrRange &Other) {
  135. return !(Other.End <= Start || End <= Other.Start);
  136. }
  137. ExecutorAddr Start;
  138. ExecutorAddr End;
  139. };
  140. inline raw_ostream &operator<<(raw_ostream &OS, const ExecutorAddr &A) {
  141. return OS << formatv("{0:x}", A.getValue());
  142. }
  143. inline raw_ostream &operator<<(raw_ostream &OS, const ExecutorAddrRange &R) {
  144. return OS << formatv("{0:x} -- {1:x}", R.Start.getValue(), R.End.getValue());
  145. }
  146. namespace shared {
  147. class SPSExecutorAddr {};
  148. /// SPS serializatior for ExecutorAddr.
  149. template <> class SPSSerializationTraits<SPSExecutorAddr, ExecutorAddr> {
  150. public:
  151. static size_t size(const ExecutorAddr &EA) {
  152. return SPSArgList<uint64_t>::size(EA.getValue());
  153. }
  154. static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddr &EA) {
  155. return SPSArgList<uint64_t>::serialize(BOB, EA.getValue());
  156. }
  157. static bool deserialize(SPSInputBuffer &BIB, ExecutorAddr &EA) {
  158. uint64_t Tmp;
  159. if (!SPSArgList<uint64_t>::deserialize(BIB, Tmp))
  160. return false;
  161. EA = ExecutorAddr(Tmp);
  162. return true;
  163. }
  164. };
  165. using SPSExecutorAddrRange = SPSTuple<SPSExecutorAddr, SPSExecutorAddr>;
  166. /// Serialization traits for address ranges.
  167. template <>
  168. class SPSSerializationTraits<SPSExecutorAddrRange, ExecutorAddrRange> {
  169. public:
  170. static size_t size(const ExecutorAddrRange &Value) {
  171. return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::size(Value.Start,
  172. Value.End);
  173. }
  174. static bool serialize(SPSOutputBuffer &BOB, const ExecutorAddrRange &Value) {
  175. return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::serialize(
  176. BOB, Value.Start, Value.End);
  177. }
  178. static bool deserialize(SPSInputBuffer &BIB, ExecutorAddrRange &Value) {
  179. return SPSArgList<SPSExecutorAddr, SPSExecutorAddr>::deserialize(
  180. BIB, Value.Start, Value.End);
  181. }
  182. };
  183. using SPSExecutorAddrRangeSequence = SPSSequence<SPSExecutorAddrRange>;
  184. } // End namespace shared.
  185. } // End namespace orc.
  186. // Provide DenseMapInfo for ExecutorAddrs.
  187. template <> struct DenseMapInfo<orc::ExecutorAddr> {
  188. static inline orc::ExecutorAddr getEmptyKey() {
  189. return orc::ExecutorAddr(DenseMapInfo<uint64_t>::getEmptyKey());
  190. }
  191. static inline orc::ExecutorAddr getTombstoneKey() {
  192. return orc::ExecutorAddr(DenseMapInfo<uint64_t>::getTombstoneKey());
  193. }
  194. static unsigned getHashValue(const orc::ExecutorAddr &Addr) {
  195. return DenseMapInfo<uint64_t>::getHashValue(Addr.getValue());
  196. }
  197. static bool isEqual(const orc::ExecutorAddr &LHS,
  198. const orc::ExecutorAddr &RHS) {
  199. return DenseMapInfo<uint64_t>::isEqual(LHS.getValue(), RHS.getValue());
  200. }
  201. };
  202. } // End namespace llvm.
  203. #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_EXECUTORADDRESS_H
  204. #ifdef __GNUC__
  205. #pragma GCC diagnostic pop
  206. #endif