1 //===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Contains a multi-threaded string pool suitable for use with ORC.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
15 #define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/StringMap.h"
25 class SymbolStringPtr;
27 /// String pool for symbol names used by the JIT.
28 class SymbolStringPool {
29 friend class SymbolStringPtr;
31 /// Destroy a SymbolStringPool.
34 /// Create a symbol string pointer from the given string.
35 SymbolStringPtr intern(StringRef S);
37 /// Remove from the pool any entries that are no longer referenced.
38 void clearDeadEntries();
40 /// Returns true if the pool is empty.
43 using RefCountType = std::atomic<size_t>;
44 using PoolMap = StringMap<RefCountType>;
45 using PoolMapEntry = StringMapEntry<RefCountType>;
46 mutable std::mutex PoolMutex;
50 /// Pointer to a pooled string representing a symbol name.
51 class SymbolStringPtr {
52 friend class SymbolStringPool;
53 friend struct DenseMapInfo<SymbolStringPtr>;
54 friend bool operator==(const SymbolStringPtr &LHS,
55 const SymbolStringPtr &RHS);
56 friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
58 static SymbolStringPool::PoolMapEntry Tombstone;
61 SymbolStringPtr() = default;
62 SymbolStringPtr(const SymbolStringPtr &Other)
68 SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
77 SymbolStringPtr(SymbolStringPtr &&Other) : S(nullptr) {
78 std::swap(S, Other.S);
81 SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
85 std::swap(S, Other.S);
94 StringRef operator*() const { return S->first(); }
98 SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
104 SymbolStringPool::PoolMapEntry *S = nullptr;
107 inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
108 return LHS.S == RHS.S;
111 inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
112 return !(LHS == RHS);
115 inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
116 return LHS.S < RHS.S;
119 inline SymbolStringPool::~SymbolStringPool() {
122 assert(Pool.empty() && "Dangling references at pool destruction time");
126 inline SymbolStringPtr SymbolStringPool::intern(StringRef S) {
127 std::lock_guard<std::mutex> Lock(PoolMutex);
130 std::tie(I, Added) = Pool.try_emplace(S, 0);
131 return SymbolStringPtr(&*I);
134 inline void SymbolStringPool::clearDeadEntries() {
135 std::lock_guard<std::mutex> Lock(PoolMutex);
136 for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
138 if (Tmp->second == 0)
143 inline bool SymbolStringPool::empty() const {
144 std::lock_guard<std::mutex> Lock(PoolMutex);
148 } // end namespace orc
151 struct DenseMapInfo<orc::SymbolStringPtr> {
153 static orc::SymbolStringPtr getEmptyKey() {
154 return orc::SymbolStringPtr();
157 static orc::SymbolStringPtr getTombstoneKey() {
158 return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone);
161 static unsigned getHashValue(orc::SymbolStringPtr V) {
162 uintptr_t IV = reinterpret_cast<uintptr_t>(V.S);
163 return unsigned(IV) ^ unsigned(IV >> 9);
166 static bool isEqual(const orc::SymbolStringPtr &LHS,
167 const orc::SymbolStringPtr &RHS) {
168 return LHS.S == RHS.S;
172 } // end namespace llvm
174 #endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H