1 //===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Contains a multi-threaded string pool suitable for use with ORC.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
15 #define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
16
17 #include "llvm/ADT/StringMap.h"
18 #include <atomic>
19 #include <mutex>
20
21 namespace llvm {
22 namespace orc {
23
24 class SymbolStringPtr;
25
26 /// String pool for symbol names used by the JIT.
27 class SymbolStringPool {
28 friend class SymbolStringPtr;
29 public:
30 /// Destroy a SymbolStringPool.
31 ~SymbolStringPool();
32
33 /// Create a symbol string pointer from the given string.
34 SymbolStringPtr intern(StringRef S);
35
36 /// Remove from the pool any entries that are no longer referenced.
37 void clearDeadEntries();
38
39 /// Returns true if the pool is empty.
40 bool empty() const;
41 private:
42 using RefCountType = std::atomic<size_t>;
43 using PoolMap = StringMap<RefCountType>;
44 using PoolMapEntry = StringMapEntry<RefCountType>;
45 mutable std::mutex PoolMutex;
46 PoolMap Pool;
47 };
48
49 /// Pointer to a pooled string representing a symbol name.
50 class SymbolStringPtr {
51 friend class SymbolStringPool;
52 friend bool operator==(const SymbolStringPtr &LHS,
53 const SymbolStringPtr &RHS);
54 friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
55
56 public:
57 SymbolStringPtr() = default;
SymbolStringPtr(const SymbolStringPtr & Other)58 SymbolStringPtr(const SymbolStringPtr &Other)
59 : S(Other.S) {
60 if (S)
61 ++S->getValue();
62 }
63
64 SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
65 if (S)
66 --S->getValue();
67 S = Other.S;
68 if (S)
69 ++S->getValue();
70 return *this;
71 }
72
SymbolStringPtr(SymbolStringPtr && Other)73 SymbolStringPtr(SymbolStringPtr &&Other) : S(nullptr) {
74 std::swap(S, Other.S);
75 }
76
77 SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
78 if (S)
79 --S->getValue();
80 S = nullptr;
81 std::swap(S, Other.S);
82 return *this;
83 }
84
~SymbolStringPtr()85 ~SymbolStringPtr() {
86 if (S)
87 --S->getValue();
88 }
89
90 StringRef operator*() const { return S->first(); }
91
92 private:
93
SymbolStringPtr(SymbolStringPool::PoolMapEntry * S)94 SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
95 : S(S) {
96 if (S)
97 ++S->getValue();
98 }
99
100 SymbolStringPool::PoolMapEntry *S = nullptr;
101 };
102
103 inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
104 return LHS.S == RHS.S;
105 }
106
107 inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
108 return !(LHS == RHS);
109 }
110
111 inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
112 return LHS.S < RHS.S;
113 }
114
~SymbolStringPool()115 inline SymbolStringPool::~SymbolStringPool() {
116 #ifndef NDEBUG
117 clearDeadEntries();
118 assert(Pool.empty() && "Dangling references at pool destruction time");
119 #endif // NDEBUG
120 }
121
intern(StringRef S)122 inline SymbolStringPtr SymbolStringPool::intern(StringRef S) {
123 std::lock_guard<std::mutex> Lock(PoolMutex);
124 PoolMap::iterator I;
125 bool Added;
126 std::tie(I, Added) = Pool.try_emplace(S, 0);
127 return SymbolStringPtr(&*I);
128 }
129
clearDeadEntries()130 inline void SymbolStringPool::clearDeadEntries() {
131 std::lock_guard<std::mutex> Lock(PoolMutex);
132 for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
133 auto Tmp = I++;
134 if (Tmp->second == 0)
135 Pool.erase(Tmp);
136 }
137 }
138
empty()139 inline bool SymbolStringPool::empty() const {
140 std::lock_guard<std::mutex> Lock(PoolMutex);
141 return Pool.empty();
142 }
143
144 } // end namespace orc
145 } // end namespace llvm
146
147 #endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
148