Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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