brintos

brintos / llvm-project-archived public Read only

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