summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h')
-rw-r--r--clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
new file mode 100644
index 00000000..39fa74bf
--- /dev/null
+++ b/clang-r353983e/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -0,0 +1,173 @@
+//===- SymbolStringPool.h - Multi-threaded pool for JIT symbols -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Contains a multi-threaded string pool suitable for use with ORC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
+#define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+#include <atomic>
+#include <mutex>
+
+namespace llvm {
+namespace orc {
+
+class SymbolStringPtr;
+
+/// String pool for symbol names used by the JIT.
+class SymbolStringPool {
+ friend class SymbolStringPtr;
+public:
+ /// Destroy a SymbolStringPool.
+ ~SymbolStringPool();
+
+ /// Create a symbol string pointer from the given string.
+ SymbolStringPtr intern(StringRef S);
+
+ /// Remove from the pool any entries that are no longer referenced.
+ void clearDeadEntries();
+
+ /// Returns true if the pool is empty.
+ bool empty() const;
+private:
+ using RefCountType = std::atomic<size_t>;
+ using PoolMap = StringMap<RefCountType>;
+ using PoolMapEntry = StringMapEntry<RefCountType>;
+ mutable std::mutex PoolMutex;
+ PoolMap Pool;
+};
+
+/// Pointer to a pooled string representing a symbol name.
+class SymbolStringPtr {
+ friend class SymbolStringPool;
+ friend struct DenseMapInfo<SymbolStringPtr>;
+ friend bool operator==(const SymbolStringPtr &LHS,
+ const SymbolStringPtr &RHS);
+ friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS);
+
+ static SymbolStringPool::PoolMapEntry Tombstone;
+
+public:
+ SymbolStringPtr() = default;
+ SymbolStringPtr(const SymbolStringPtr &Other)
+ : S(Other.S) {
+ if (S)
+ ++S->getValue();
+ }
+
+ SymbolStringPtr& operator=(const SymbolStringPtr &Other) {
+ if (S)
+ --S->getValue();
+ S = Other.S;
+ if (S)
+ ++S->getValue();
+ return *this;
+ }
+
+ SymbolStringPtr(SymbolStringPtr &&Other) : S(nullptr) {
+ std::swap(S, Other.S);
+ }
+
+ SymbolStringPtr& operator=(SymbolStringPtr &&Other) {
+ if (S)
+ --S->getValue();
+ S = nullptr;
+ std::swap(S, Other.S);
+ return *this;
+ }
+
+ ~SymbolStringPtr() {
+ if (S)
+ --S->getValue();
+ }
+
+ StringRef operator*() const { return S->first(); }
+
+private:
+
+ SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
+ : S(S) {
+ if (S)
+ ++S->getValue();
+ }
+
+ SymbolStringPool::PoolMapEntry *S = nullptr;
+};
+
+inline bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
+ return LHS.S == RHS.S;
+}
+
+inline bool operator!=(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
+ return !(LHS == RHS);
+}
+
+inline bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS) {
+ return LHS.S < RHS.S;
+}
+
+inline SymbolStringPool::~SymbolStringPool() {
+#ifndef NDEBUG
+ clearDeadEntries();
+ assert(Pool.empty() && "Dangling references at pool destruction time");
+#endif // NDEBUG
+}
+
+inline SymbolStringPtr SymbolStringPool::intern(StringRef S) {
+ std::lock_guard<std::mutex> Lock(PoolMutex);
+ PoolMap::iterator I;
+ bool Added;
+ std::tie(I, Added) = Pool.try_emplace(S, 0);
+ return SymbolStringPtr(&*I);
+}
+
+inline void SymbolStringPool::clearDeadEntries() {
+ std::lock_guard<std::mutex> Lock(PoolMutex);
+ for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
+ auto Tmp = I++;
+ if (Tmp->second == 0)
+ Pool.erase(Tmp);
+ }
+}
+
+inline bool SymbolStringPool::empty() const {
+ std::lock_guard<std::mutex> Lock(PoolMutex);
+ return Pool.empty();
+}
+
+} // end namespace orc
+
+template <>
+struct DenseMapInfo<orc::SymbolStringPtr> {
+
+ static orc::SymbolStringPtr getEmptyKey() {
+ return orc::SymbolStringPtr();
+ }
+
+ static orc::SymbolStringPtr getTombstoneKey() {
+ return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone);
+ }
+
+ static unsigned getHashValue(orc::SymbolStringPtr V) {
+ uintptr_t IV = reinterpret_cast<uintptr_t>(V.S);
+ return unsigned(IV) ^ unsigned(IV >> 9);
+ }
+
+ static bool isEqual(const orc::SymbolStringPtr &LHS,
+ const orc::SymbolStringPtr &RHS) {
+ return LHS.S == RHS.S;
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H