diff options
Diffstat (limited to 'clang-r353983/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h')
| -rw-r--r-- | clang-r353983/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/clang-r353983/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h new file mode 100644 index 00000000..39fa74bf --- /dev/null +++ b/clang-r353983/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 |
