Use a single allocation for SharedString::Storage
This commit is contained in:
parent
39689f0a18
commit
3697548e35
|
@ -35,7 +35,7 @@ void StringRegistry::debug_stats() const
|
||||||
for (auto& st : m_strings)
|
for (auto& st : m_strings)
|
||||||
{
|
{
|
||||||
total_refcount += st.second->refcount - 1;
|
total_refcount += st.second->refcount - 1;
|
||||||
total_size += (int)st.second->content.size();
|
total_size += (int)st.second->length;
|
||||||
}
|
}
|
||||||
write_debug(" data size: " + to_string(total_size) + ", mean: " + to_string((float)total_size/count));
|
write_debug(" data size: " + to_string(total_size) + ", mean: " + to_string((float)total_size/count));
|
||||||
write_debug(" refcounts: " + to_string(total_refcount) + ", mean: " + to_string((float)total_refcount/count));
|
write_debug(" refcounts: " + to_string(total_refcount) + ", mean: " + to_string((float)total_refcount/count));
|
||||||
|
|
|
@ -14,19 +14,31 @@ class SharedString : public StringView
|
||||||
public:
|
public:
|
||||||
struct Storage : UseMemoryDomain<MemoryDomain::SharedString>
|
struct Storage : UseMemoryDomain<MemoryDomain::SharedString>
|
||||||
{
|
{
|
||||||
int refcount = 0;
|
int refcount;
|
||||||
Vector<char, MemoryDomain::SharedString> content;
|
int length;
|
||||||
|
char data[1];
|
||||||
|
|
||||||
Storage(StringView str)
|
StringView strview() const { return {data, length}; }
|
||||||
|
|
||||||
|
static Storage* create(StringView str)
|
||||||
{
|
{
|
||||||
content.reserve((int)str.length() + 1);
|
const int len = (int)str.length();
|
||||||
content.assign(str.begin(), str.end());
|
void* ptr = Storage::operator new(sizeof(Storage) + len);
|
||||||
content.push_back('\0');
|
Storage* res = reinterpret_cast<Storage*>(ptr);
|
||||||
|
memcpy(res->data, str.data(), len);
|
||||||
|
res->refcount = 0;
|
||||||
|
res->length = len;
|
||||||
|
res->data[len] = 0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy(Storage* s)
|
||||||
|
{
|
||||||
|
Storage::operator delete(s, sizeof(Storage) + s->length);
|
||||||
}
|
}
|
||||||
StringView strview() const { return {&content.front(), &content.back()}; }
|
|
||||||
|
|
||||||
friend void inc_ref_count(Storage* s) { ++s->refcount; }
|
friend void inc_ref_count(Storage* s) { ++s->refcount; }
|
||||||
friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) delete s; }
|
friend void dec_ref_count(Storage* s) { if (--s->refcount == 0) Storage::destroy(s); }
|
||||||
};
|
};
|
||||||
|
|
||||||
SharedString() = default;
|
SharedString() = default;
|
||||||
|
@ -34,7 +46,7 @@ public:
|
||||||
{
|
{
|
||||||
if (not str.empty())
|
if (not str.empty())
|
||||||
{
|
{
|
||||||
m_storage = new Storage{str};
|
m_storage = Storage::create(str);
|
||||||
StringView::operator=(m_storage->strview());
|
StringView::operator=(m_storage->strview());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user