13#include "llvm/ADT/StringMap.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/iterator.h"
16#include "llvm/Support/Allocator.h"
17#include "llvm/Support/DJB.h"
18#include "llvm/Support/FormatProviders.h"
19#include "llvm/Support/Threading.h"
23#include <shared_mutex>
32#if !defined(__APPLE__)
46 void lock() { os_unfair_lock_lock(&m_lock); }
47 void unlock() { os_unfair_lock_unlock(&m_lock); }
48 void lock_shared() { os_unfair_lock_lock(&m_lock); }
49 void unlock_shared() { os_unfair_lock_unlock(&m_lock); }
52 os_unfair_lock m_lock = OS_UNFAIR_LOCK_INIT;
89 typedef llvm::StringMap<StringPoolValueType, Allocator>
StringPool;
94 return StringPoolEntryType::GetStringMapEntryFromKeyData(keyData);
98 if (ccstr !=
nullptr) {
102 return entry.getKeyLength();
108 const char *
const ccstr = str.data();
109 if (ccstr !=
nullptr) {
111 std::shared_lock<PoolMutex> lock(pool.
m_mutex);
130 if (string_ref.data()) {
131 const uint32_t string_hash = StringPool::hash(string_ref);
135 std::shared_lock<PoolMutex> lock(pool.
m_mutex);
136 auto it = pool.
m_string_map.find(string_ref, string_hash);
138 return it->getKeyData();
141 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
144 .insert(std::make_pair(string_ref,
nullptr), string_hash)
146 return entry.getKeyData();
152 llvm::StringRef mangled) {
153 const char *demangled_ccstr =
nullptr;
154 const char *
const mangled_ccstr = mangled.data();
157 const uint32_t demangled_hash = StringPool::hash(demangled);
159 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
164 *map.try_emplace_with_hash(demangled, demangled_hash).first;
166 entry.second = mangled_ccstr;
169 demangled_ccstr = entry.getKeyData();
176 std::lock_guard<PoolMutex> lock(pool.
m_mutex);
181 return demangled_ccstr;
186 if (cstr !=
nullptr) {
187 const size_t trimmed_len = strnlen(cstr, cstr_len);
196 std::shared_lock<PoolMutex> lock(pool.m_mutex);
197 const Allocator &alloc = pool.m_string_map.getAllocator();
199 stats.
bytes_used += alloc.getBytesAllocated();
217 return m_string_pools[((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff];
230 static llvm::once_flag g_pool_initialization_flag;
231 static Pool *g_string_pool =
nullptr;
233 llvm::call_once(g_pool_initialization_flag,
234 []() { g_string_pool =
new Pool(); });
236 return *g_string_pool;
256 if (lhs_string_ref.data() && rhs_string_ref.data())
257 return lhs_string_ref < rhs_string_ref;
260 return lhs_string_ref.data() ==
nullptr;
276 const bool case_sensitive) {
289 return lhs_string_ref.equals_insensitive(rhs_string_ref);
293 const bool case_sensitive) {
295 const char *lhs_cstr = lhs.
m_string;
296 const char *rhs_cstr = rhs.
m_string;
297 if (lhs_cstr == rhs_cstr)
299 if (lhs_cstr && rhs_cstr) {
303 if (case_sensitive) {
304 return lhs_string_ref.compare(rhs_string_ref);
306 return lhs_string_ref.compare_insensitive(rhs_string_ref);
318 const char *cstr =
AsCString(fail_value);
328 const char *parens = cstr ?
"\"" :
"";
329 s->
Printf(
"%*p: ConstString, string = %s%s%s, length = %" PRIu64,
330 static_cast<int>(
sizeof(
void *) * 2),
331 static_cast<const void *
>(
this), parens, cstr, parens,
332 static_cast<uint64_t
>(cstr_len));
351 return (
bool)counterpart;
367void llvm::format_provider<ConstString>::format(
const ConstString &CS,
368 llvm::raw_ostream &
OS,
std::shared_mutex PoolMutex
static Pool & StringPool()
PoolEntry & selectPool(const llvm::StringRef &s)
static const size_t SizeThreshold
static StringPoolEntryType & GetStringMapEntryFromKeyData(const char *keyData)
const char * GetConstCStringWithStringRef(llvm::StringRef string_ref)
static const size_t AllocatorSlabSize
The default BumpPtrAllocatorImpl slab size.
llvm::StringMap< StringPoolValueType, Allocator > StringPool
const char * GetConstCStringWithLength(const char *cstr, size_t cstr_len)
StringPoolValueType GetMangledCounterpart(llvm::StringRef str)
const char * GetConstCStringAndSetMangledCounterPart(llvm::StringRef demangled, llvm::StringRef mangled)
const char * GetConstTrimmedCStringWithLength(const char *cstr, size_t cstr_len)
ConstString::MemoryStats GetMemoryStats() const
llvm::BumpPtrAllocatorImpl< llvm::MallocAllocator, AllocatorSlabSize, SizeThreshold, AllocatorGrowthDelay > Allocator
std::array< PoolEntry, 256 > m_string_pools
llvm::StringMapEntry< StringPoolValueType > StringPoolEntryType
const char * GetConstCString(const char *cstr)
PoolEntry & selectPool(uint32_t h)
static const size_t AllocatorGrowthDelay
Every Pool has its own allocator which receives an equal share of the ConstString allocations.
const char * StringPoolValueType
static size_t GetConstCStringLength(const char *ccstr)
A uniqued constant string class.
bool GetMangledCounterpart(ConstString &counterpart) const
Retrieve the mangled or demangled counterpart for a mangled or demangled ConstString.
static MemoryStats GetMemoryStats()
void SetCStringWithLength(const char *cstr, size_t cstr_len)
Set the C string value with length.
void SetCString(const char *cstr)
Set the C string value.
static int Compare(ConstString lhs, ConstString rhs, const bool case_sensitive=true)
Compare two string objects.
ConstString()=default
Default constructor.
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
static bool Equals(ConstString lhs, ConstString rhs, const bool case_sensitive=true)
Equal to operator.
void DumpDebug(Stream *s) const
Dump the object debug description to a stream.
void SetTrimmedCStringWithLength(const char *cstr, size_t fixed_cstr_len)
Set the C string value with the minimum length between fixed_cstr_len and the actual length of the C ...
size_t GetLength() const
Get the length in bytes of string value.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
void SetString(llvm::StringRef s)
bool operator<(ConstString rhs) const
const char * GetCString() const
Get the string value as a C string.
void SetStringWithMangledCounterpart(llvm::StringRef demangled, ConstString mangled)
Set the C string value and its mangled counterpart.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
A command line option parsing protocol class.
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
A class that represents a running process on the host machine.
Stream & operator<<(Stream &s, const Mangled &obj)