blob: da40d1caaabef8357c0c3f4725d774bf5c8f4ee3 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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
21namespace llvm {
22namespace orc {
23
24class SymbolStringPtr;
25
26/// @brief String pool for symbol names used by the JIT.
27class SymbolStringPool {
28 friend class SymbolStringPtr;
29public:
30 /// @brief Create a symbol string pointer from the given string.
31 SymbolStringPtr intern(StringRef S);
32
33 /// @brief Remove from the pool any entries that are no longer referenced.
34 void clearDeadEntries();
35
36 /// @brief Returns true if the pool is empty.
37 bool empty() const;
38private:
39 using RefCountType = std::atomic<size_t>;
40 using PoolMap = StringMap<RefCountType>;
41 using PoolMapEntry = StringMapEntry<RefCountType>;
42 mutable std::mutex PoolMutex;
43 PoolMap Pool;
44};
45
46/// @brief Pointer to a pooled string representing a symbol name.
47class SymbolStringPtr {
48 friend class SymbolStringPool;
49 friend bool operator==(const SymbolStringPtr &LHS,
50 const SymbolStringPtr &RHS);
51 friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
52
53public:
54 SymbolStringPtr() = default;
55 SymbolStringPtr(const SymbolStringPtr &Other)
56 : S(Other.S) {
57 if (S)
58 ++S->getValue();
59 }
60
61 SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
62 if (S)
63 --S->getValue();
64 S = Other.S;
65 if (S)
66 ++S->getValue();
67 return *this;
68 }
69
70 SymbolStringPtr(SymbolStringPtr &&Other) : S(nullptr) {
71 std::swap(S, Other.S);
72 }
73
74 SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
75 if (S)
76 --S->getValue();
77 S = nullptr;
78 std::swap(S, Other.S);
79 return *this;
80 }
81
82 ~SymbolStringPtr() {
83 if (S)
84 --S->getValue();
85 }
86
87 StringRef operator*() const { return S->first(); }
88
89private:
90
91 SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
92 : S(S) {
93 if (S)
94 ++S->getValue();
95 }
96
97 SymbolStringPool::PoolMapEntry *S = nullptr;
98};
99
100inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
101 return LHS.S == RHS.S;
102}
103
104inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
105 return !(LHS == RHS);
106}
107
108inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
109 return LHS.S < RHS.S;
110}
111
112inline SymbolStringPtr SymbolStringPool::intern(StringRef S) {
113 std::lock_guard<std::mutex> Lock(PoolMutex);
114 PoolMap::iterator I;
115 bool Added;
116 std::tie(I, Added) = Pool.try_emplace(S, 0);
117 return SymbolStringPtr(&*I);
118}
119
120inline void SymbolStringPool::clearDeadEntries() {
121 std::lock_guard<std::mutex> Lock(PoolMutex);
122 for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
123 auto Tmp = I++;
124 if (Tmp->second == 0)
125 Pool.erase(Tmp);
126 }
127}
128
129inline bool SymbolStringPool::empty() const {
130 std::lock_guard<std::mutex> Lock(PoolMutex);
131 return Pool.empty();
132}
133
134} // end namespace orc
135} // end namespace llvm
136
137#endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H