11#include "llvm/ADT/StringMap.h"
12#include "llvm/Support/Allocator.h"
13#include "llvm/Support/Threading.h"
17#include <shared_mutex>
25#if !defined(__APPLE__)
39 void lock() { os_unfair_lock_lock(&m_lock); }
40 void unlock() { os_unfair_lock_unlock(&m_lock); }
41 void lock_shared() { os_unfair_lock_lock(&m_lock); }
42 void unlock_shared() { os_unfair_lock_unlock(&m_lock); }
45 os_unfair_lock m_lock = OS_UNFAIR_LOCK_INIT;
52constexpr size_t AllocatorSlabSize = 4096;
53constexpr size_t SizeThreshold = AllocatorSlabSize;
54constexpr size_t NumPools = 256;
76constexpr size_t AllocatorGrowthDelay = 1;
78 llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, AllocatorSlabSize,
79 SizeThreshold, AllocatorGrowthDelay>;
80using StringPoolValueType =
const char *;
81using StringMapType = llvm::StringMap<StringPoolValueType, Allocator>;
82using StringPoolEntryType = llvm::StringMapEntry<StringPoolValueType>;
84StringPoolEntryType &GetStringMapEntryFromKeyData(
const char *keyData) {
85 return StringPoolEntryType::GetStringMapEntryFromKeyData(keyData);
110 static llvm::once_flag g_pool_initialization_flag;
113 llvm::call_once(g_pool_initialization_flag,
116 return *g_string_pool;
134 return m_string_pools[((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff];
142 if (ccstr !=
nullptr) {
145 const StringPoolEntryType &entry = GetStringMapEntryFromKeyData(ccstr);
146 return entry.getKeyLength();
152 const char *
const ccstr = str.data();
153 if (ccstr !=
nullptr) {
155 std::shared_lock<PoolMutex> lock(pool.
m_mutex);
156 return GetStringMapEntryFromKeyData(ccstr).getValue();
170 return Intern(llvm::StringRef(cstr, cstr_len));
175 if (string_ref.data()) {
176 const uint32_t string_hash = StringMapType::hash(string_ref);
180 std::shared_lock<PoolMutex> lock(pool.
m_mutex);
181 auto it = pool.
m_string_map.find(string_ref, string_hash);
183 return it->getKeyData();
186 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
188 StringPoolEntryType &entry =
190 .insert(std::make_pair(string_ref,
nullptr), string_hash)
192 return entry.getKeyData();
199 llvm::StringRef mangled) {
200 const char *demangled_ccstr =
nullptr;
201 const char *
const mangled_ccstr = mangled.data();
204 const uint32_t demangled_hash = StringMapType::hash(demangled);
206 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
210 auto [entry, inserted] =
211 map.try_emplace_with_hash(demangled, demangled_hash);
215 entry->second = mangled_ccstr;
218 demangled_ccstr = entry->getKeyData();
225 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
226 GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr);
230 return demangled_ccstr;
235 if (cstr !=
nullptr) {
236 const size_t trimmed_len = strnlen(cstr, cstr_len);
244 for (
size_t i = 0; i < NumPools; ++i) {
246 std::shared_lock<PoolMutex> lock(pool.
m_mutex);
247 const Allocator &alloc = pool.
m_string_map.getAllocator();
std::shared_mutex PoolMutex
static StringPool * g_system_pool
A handle to a StringPool that does not own it.
A thread-safe pool of interned, null-terminated strings.
std::unique_ptr< PoolEntry[]> m_string_pools
const char * GetConstCString(const char *cstr)
PoolEntry & selectPool(uint32_t hash)
const char * Intern(llvm::StringRef str)
Returns the pooled copy of str, or nullptr if str has no data.
const char * GetMangledCounterpart(llvm::StringRef str)
static StringPoolRef GetSystemPool()
The system pool. Only valid between Initialize and Terminate.
ConstString::MemoryStats GetMemoryStats() const
const char * GetConstCStringWithLength(const char *cstr, size_t cstr_len)
static StringPool & GetGlobal()
The pool backing ConstString. It is never destroyed.
static size_t GetConstCStringLength(const char *ccstr)
Length of a string returned by any pool.
static void Initialize()
Set up and tear down the system pool, for strings that are not owned by a Debugger.
const char * GetConstTrimmedCStringWithLength(const char *cstr, size_t cstr_len)
const char * GetConstCStringAndSetMangledCounterPart(llvm::StringRef demangled, llvm::StringRef mangled)
Interns demangled and links it with the already interned mangled.
A class that represents a running process on the host machine.
StringMapType m_string_map
std::size_t used_bytes
The exact number of bytes used by this pool.