1 //===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Contains a multi-threaded string pool suitable for use with ORC.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
14 #define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringMap.h"
24 class SymbolStringPtr
;
26 /// String pool for symbol names used by the JIT.
27 class SymbolStringPool
{
28 friend class SymbolStringPtr
;
30 /// Destroy a SymbolStringPool.
33 /// Create a symbol string pointer from the given string.
34 SymbolStringPtr
intern(StringRef S
);
36 /// Remove from the pool any entries that are no longer referenced.
37 void clearDeadEntries();
39 /// Returns true if the pool is empty.
42 using RefCountType
= std::atomic
<size_t>;
43 using PoolMap
= StringMap
<RefCountType
>;
44 using PoolMapEntry
= StringMapEntry
<RefCountType
>;
45 mutable std::mutex PoolMutex
;
49 /// Pointer to a pooled string representing a symbol name.
50 class SymbolStringPtr
{
51 friend class SymbolStringPool
;
52 friend struct DenseMapInfo
<SymbolStringPtr
>;
53 friend bool operator==(const SymbolStringPtr
&LHS
,
54 const SymbolStringPtr
&RHS
);
55 friend bool operator<(const SymbolStringPtr
&LHS
, const SymbolStringPtr
&RHS
);
57 static SymbolStringPool::PoolMapEntry Tombstone
;
60 SymbolStringPtr() = default;
61 SymbolStringPtr(const SymbolStringPtr
&Other
)
67 SymbolStringPtr
& operator=(const SymbolStringPtr
&Other
) {
76 SymbolStringPtr(SymbolStringPtr
&&Other
) : S(nullptr) {
77 std::swap(S
, Other
.S
);
80 SymbolStringPtr
& operator=(SymbolStringPtr
&&Other
) {
84 std::swap(S
, Other
.S
);
93 StringRef
operator*() const { return S
->first(); }
97 SymbolStringPtr(SymbolStringPool::PoolMapEntry
*S
)
103 SymbolStringPool::PoolMapEntry
*S
= nullptr;
106 inline bool operator==(const SymbolStringPtr
&LHS
, const SymbolStringPtr
&RHS
) {
107 return LHS
.S
== RHS
.S
;
110 inline bool operator!=(const SymbolStringPtr
&LHS
, const SymbolStringPtr
&RHS
) {
111 return !(LHS
== RHS
);
114 inline bool operator<(const SymbolStringPtr
&LHS
, const SymbolStringPtr
&RHS
) {
115 return LHS
.S
< RHS
.S
;
118 inline SymbolStringPool::~SymbolStringPool() {
121 assert(Pool
.empty() && "Dangling references at pool destruction time");
125 inline SymbolStringPtr
SymbolStringPool::intern(StringRef S
) {
126 std::lock_guard
<std::mutex
> Lock(PoolMutex
);
129 std::tie(I
, Added
) = Pool
.try_emplace(S
, 0);
130 return SymbolStringPtr(&*I
);
133 inline void SymbolStringPool::clearDeadEntries() {
134 std::lock_guard
<std::mutex
> Lock(PoolMutex
);
135 for (auto I
= Pool
.begin(), E
= Pool
.end(); I
!= E
;) {
137 if (Tmp
->second
== 0)
142 inline bool SymbolStringPool::empty() const {
143 std::lock_guard
<std::mutex
> Lock(PoolMutex
);
147 } // end namespace orc
150 struct DenseMapInfo
<orc::SymbolStringPtr
> {
152 static orc::SymbolStringPtr
getEmptyKey() {
153 return orc::SymbolStringPtr();
156 static orc::SymbolStringPtr
getTombstoneKey() {
157 return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone
);
160 static unsigned getHashValue(orc::SymbolStringPtr V
) {
161 uintptr_t IV
= reinterpret_cast<uintptr_t>(V
.S
);
162 return unsigned(IV
) ^ unsigned(IV
>> 9);
165 static bool isEqual(const orc::SymbolStringPtr
&LHS
,
166 const orc::SymbolStringPtr
&RHS
) {
167 return LHS
.S
== RHS
.S
;
171 } // end namespace llvm
173 #endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H