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);
164 for (
const auto &pool : m_string_pools) {
165 llvm::sys::SmartScopedReader<false> rlock(pool.m_mutex);
166 const Allocator &alloc = pool.m_string_map.getAllocator();
168 stats.
bytes_used += alloc.getBytesAllocated();
174 uint8_t
hash(
const llvm::StringRef &s)
const {
176 return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff;
180 mutable llvm::sys::SmartRWMutex<false>
m_mutex;
196 static llvm::once_flag g_pool_initialization_flag;
197 static Pool *g_string_pool =
nullptr;
199 llvm::call_once(g_pool_initialization_flag,
200 []() { g_string_pool =
new Pool(); });
202 return *g_string_pool;
206 : m_string(
StringPool().GetConstCString(cstr)) {}
209 : m_string(
StringPool().GetConstCStringWithLength(cstr, cstr_len)) {}
212 : m_string(
StringPool().GetConstCStringWithStringRef(s)) {}
222 if (lhs_string_ref.data() && rhs_string_ref.data())
223 return lhs_string_ref < rhs_string_ref;
226 return lhs_string_ref.data() ==
nullptr;
242 const bool case_sensitive) {
255 return lhs_string_ref.equals_insensitive(rhs_string_ref);
259 const bool case_sensitive) {
261 const char *lhs_cstr = lhs.
m_string;
262 const char *rhs_cstr = rhs.
m_string;
263 if (lhs_cstr == rhs_cstr)
265 if (lhs_cstr && rhs_cstr) {
269 if (case_sensitive) {
270 return lhs_string_ref.compare(rhs_string_ref);
272 return lhs_string_ref.compare_insensitive(rhs_string_ref);
284 const char *cstr =
AsCString(fail_value);
294 const char *parens = cstr ?
"\"" :
"";
295 s->
Printf(
"%*p: ConstString, string = %s%s%s, length = %" PRIu64,
296 static_cast<int>(
sizeof(
void *) * 2),
297 static_cast<const void *
>(
this), parens, cstr, parens,
298 static_cast<uint64_t
>(cstr_len));
317 return (
bool)counterpart;
333 void llvm::format_provider<ConstString>::format(
const ConstString &CS,
334 llvm::raw_ostream &OS,
339 void llvm::yaml::ScalarTraits<ConstString>::output(
const ConstString &Val,
340 void *, raw_ostream &Out) {
345 llvm::yaml::ScalarTraits<ConstString>::input(llvm::StringRef
Scalar,
void *,