13 #include "llvm/ADT/StringMap.h"
14 #include "llvm/ADT/iterator.h"
15 #include "llvm/Support/Allocator.h"
16 #include "llvm/Support/DJB.h"
17 #include "llvm/Support/FormatProviders.h"
18 #include "llvm/Support/RWMutex.h"
19 #include "llvm/Support/Threading.h"
33 static const size_t AllocatorSlabSize = 4096;
34 static const size_t SizeThreshold = AllocatorSlabSize;
57 static const size_t AllocatorGrowthDelay = 1;
58 typedef llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, AllocatorSlabSize,
59 SizeThreshold, AllocatorGrowthDelay>
62 typedef llvm::StringMap<StringPoolValueType, Allocator>
StringPool;
67 return StringPoolEntryType::GetStringMapEntryFromKeyData(keyData);
71 if (ccstr !=
nullptr) {
75 return entry.getKey().size();
81 if (ccstr !=
nullptr) {
82 const uint8_t h = hash(llvm::StringRef(ccstr));
83 llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
84 return GetStringMapEntryFromKeyData(ccstr).getValue();
91 return GetConstCStringWithLength(cstr, strlen(cstr));
97 return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len));
102 if (string_ref.data()) {
103 const uint8_t h = hash(string_ref);
106 llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
107 auto it = m_string_pools[h].m_string_map.find(string_ref);
108 if (it != m_string_pools[h].m_string_map.end())
109 return it->getKeyData();
112 llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
115 .m_string_map.insert(std::make_pair(string_ref,
nullptr))
117 return entry.getKeyData();
124 const char *mangled_ccstr) {
125 const char *demangled_ccstr =
nullptr;
128 const uint8_t h = hash(demangled);
129 llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
132 StringPool &map = m_string_pools[h].m_string_map;
135 entry.second = mangled_ccstr;
138 demangled_ccstr = entry.getKeyData();
144 const uint8_t h = hash(llvm::StringRef(mangled_ccstr));
145 llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex);
146 GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr);
150 return demangled_ccstr;
155 if (cstr !=
nullptr) {
156 const size_t trimmed_len = strnlen(cstr, cstr_len);
157 return GetConstCStringWithLength(cstr, trimmed_len);
165 size_t mem_size =
sizeof(
Pool);
166 for (
const auto &pool : m_string_pools) {
167 llvm::sys::SmartScopedReader<false> rlock(pool.m_mutex);
168 for (
const auto &entry : pool.m_string_map)
175 uint8_t
hash(
const llvm::StringRef &s)
const {
177 return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff;
181 mutable llvm::sys::SmartRWMutex<false>
m_mutex;
197 static llvm::once_flag g_pool_initialization_flag;
198 static Pool *g_string_pool =
nullptr;
200 llvm::call_once(g_pool_initialization_flag,
201 []() { g_string_pool =
new Pool(); });
203 return *g_string_pool;
207 : m_string(
StringPool().GetConstCString(cstr)) {}
210 : m_string(
StringPool().GetConstCStringWithLength(cstr, cstr_len)) {}
213 : m_string(
StringPool().GetConstCStringWithStringRef(s)) {}
223 if (lhs_string_ref.data() && rhs_string_ref.data())
224 return lhs_string_ref < rhs_string_ref;
227 return lhs_string_ref.data() ==
nullptr;
243 const bool case_sensitive) {
256 return lhs_string_ref.equals_lower(rhs_string_ref);
260 const bool case_sensitive) {
262 const char *lhs_cstr = lhs.
m_string;
263 const char *rhs_cstr = rhs.
m_string;
264 if (lhs_cstr == rhs_cstr)
266 if (lhs_cstr && rhs_cstr) {
270 if (case_sensitive) {
271 return lhs_string_ref.compare(rhs_string_ref);
273 return lhs_string_ref.compare_lower(rhs_string_ref);
285 const char *cstr =
AsCString(fail_value);
295 const char *parens = cstr ?
"\"" :
"";
296 s->
Printf(
"%*p: ConstString, string = %s%s%s, length = %" PRIu64,
297 static_cast<int>(
sizeof(
void *) * 2),
298 static_cast<const void *
>(
this), parens, cstr, parens,
299 static_cast<uint64_t
>(cstr_len));
318 return (
bool)counterpart;
335 void llvm::format_provider<ConstString>::format(
const ConstString &CS,
336 llvm::raw_ostream &OS,
341 void llvm::yaml::ScalarTraits<ConstString>::output(
const ConstString &Val,
342 void *, raw_ostream &Out) {
347 llvm::yaml::ScalarTraits<ConstString>::input(llvm::StringRef
Scalar,
void *,