From 3b31636985c00afaee721b5aef05cac956c6284b Mon Sep 17 00:00:00 2001 From: Lukas Tenbrink Date: Fri, 25 Apr 2025 19:22:29 +0200 Subject: [PATCH] Remove unnecessary `StringName` `idx` cache in `_Data` to reduce its size by 4 bytes. Encapsulate `StringName` details in its cpp file. --- core/string/string_name.cpp | 113 ++++++++++++++++-------------------- core/string/string_name.h | 15 +---- 2 files changed, 52 insertions(+), 76 deletions(-) diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp index b68a075a741d..de462cf402d4 100644 --- a/core/string/string_name.cpp +++ b/core/string/string_name.cpp @@ -33,38 +33,31 @@ #include "core/os/os.h" #include "core/string/print_string.h" -bool StringName::_Data::operator==(const String &p_name) const { - return name == p_name; -} - -bool StringName::_Data::operator!=(const String &p_name) const { - return !operator==(p_name); -} +struct StringName::Table { + constexpr static uint32_t TABLE_BITS = 16; + constexpr static uint32_t TABLE_LEN = 1 << TABLE_BITS; + constexpr static uint32_t TABLE_MASK = TABLE_LEN - 1; -bool StringName::_Data::operator==(const char *p_name) const { - return name == p_name; -} - -bool StringName::_Data::operator!=(const char *p_name) const { - return !operator==(p_name); -} + static inline _Data *table[TABLE_LEN]; + static inline Mutex mutex; +}; void StringName::setup() { ERR_FAIL_COND(configured); - for (int i = 0; i < STRING_TABLE_LEN; i++) { - _table[i] = nullptr; + for (uint32_t i = 0; i < Table::TABLE_LEN; i++) { + Table::table[i] = nullptr; } configured = true; } void StringName::cleanup() { - MutexLock lock(mutex); + MutexLock lock(Table::mutex); #ifdef DEBUG_ENABLED if (unlikely(debug_stringname)) { Vector<_Data *> data; - for (int i = 0; i < STRING_TABLE_LEN; i++) { - _Data *d = _table[i]; + for (uint32_t i = 0; i < Table::TABLE_LEN; i++) { + _Data *d = Table::table[i]; while (d) { data.push_back(d); d = d->next; @@ -77,7 +70,7 @@ void StringName::cleanup() { int unreferenced_stringnames = 0; int rarely_referenced_stringnames = 0; for (int i = 0; i < data.size(); i++) { - print_line(itos(i + 1) + ": " + data[i]->get_name() + " - " + itos(data[i]->debug_references)); + print_line(itos(i + 1) + ": " + data[i]->name + " - " + itos(data[i]->debug_references)); if (data[i]->debug_references == 0) { unreferenced_stringnames += 1; } else if (data[i]->debug_references < 5) { @@ -90,9 +83,9 @@ void StringName::cleanup() { } #endif int lost_strings = 0; - for (int i = 0; i < STRING_TABLE_LEN; i++) { - while (_table[i]) { - _Data *d = _table[i]; + for (uint32_t i = 0; i < Table::TABLE_LEN; i++) { + while (Table::table[i]) { + _Data *d = Table::table[i]; if (d->static_count.get() != d->refcount.get()) { lost_strings++; @@ -101,7 +94,7 @@ void StringName::cleanup() { } } - _table[i] = _table[i]->next; + Table::table[i] = Table::table[i]->next; memdelete(d); } } @@ -115,7 +108,7 @@ void StringName::unref() { ERR_FAIL_COND(!configured); if (_data && _data->refcount.unref()) { - MutexLock lock(mutex); + MutexLock lock(Table::mutex); if (CoreGlobals::leak_reporting_enabled && _data->static_count.get() > 0) { ERR_PRINT("BUG: Unreferenced static string to 0: " + _data->name); @@ -123,10 +116,8 @@ void StringName::unref() { if (_data->prev) { _data->prev->next = _data->next; } else { - if (_table[_data->idx] != _data) { - ERR_PRINT("BUG!"); - } - _table[_data->idx] = _data->next; + const uint32_t idx = _data->hash & Table::TABLE_MASK; + Table::table[idx] = _data->next; } if (_data->next) { @@ -145,7 +136,7 @@ uint32_t StringName::get_empty_hash() { bool StringName::operator==(const String &p_name) const { if (_data) { - return _data->operator==(p_name); + return _data->name == p_name; } return p_name.is_empty(); @@ -153,7 +144,7 @@ bool StringName::operator==(const String &p_name) const { bool StringName::operator==(const char *p_name) const { if (_data) { - return _data->operator==(p_name); + return _data->name == p_name; } return p_name[0] == 0; @@ -217,7 +208,7 @@ StringName::StringName(const StringName &p_name) { } void StringName::assign_static_unique_class_name(StringName *ptr, const char *p_name) { - MutexLock lock(mutex); + MutexLock lock(Table::mutex); if (*ptr == StringName()) { *ptr = StringName(p_name, true); } @@ -233,14 +224,14 @@ StringName::StringName(const char *p_name, bool p_static) { } const uint32_t hash = String::hash(p_name); - const uint32_t idx = hash & STRING_TABLE_MASK; + const uint32_t idx = hash & Table::TABLE_MASK; - MutexLock lock(mutex); - _data = _table[idx]; + MutexLock lock(Table::mutex); + _data = Table::table[idx]; while (_data) { // compare hash first - if (_data->hash == hash && _data->operator==(p_name)) { + if (_data->hash == hash && _data->name == p_name) { break; } _data = _data->next; @@ -264,8 +255,7 @@ StringName::StringName(const char *p_name, bool p_static) { _data->refcount.init(); _data->static_count.set(p_static ? 1 : 0); _data->hash = hash; - _data->idx = idx; - _data->next = _table[idx]; + _data->next = Table::table[idx]; _data->prev = nullptr; #ifdef DEBUG_ENABLED @@ -275,10 +265,10 @@ StringName::StringName(const char *p_name, bool p_static) { _data->static_count.increment(); } #endif - if (_table[idx]) { - _table[idx]->prev = _data; + if (Table::table[idx]) { + Table::table[idx]->prev = _data; } - _table[idx] = _data; + Table::table[idx] = _data; } StringName::StringName(const String &p_name, bool p_static) { @@ -291,13 +281,13 @@ StringName::StringName(const String &p_name, bool p_static) { } const uint32_t hash = p_name.hash(); - const uint32_t idx = hash & STRING_TABLE_MASK; + const uint32_t idx = hash & Table::TABLE_MASK; - MutexLock lock(mutex); - _data = _table[idx]; + MutexLock lock(Table::mutex); + _data = Table::table[idx]; while (_data) { - if (_data->hash == hash && _data->operator==(p_name)) { + if (_data->hash == hash && _data->name == p_name) { break; } _data = _data->next; @@ -321,8 +311,7 @@ StringName::StringName(const String &p_name, bool p_static) { _data->refcount.init(); _data->static_count.set(p_static ? 1 : 0); _data->hash = hash; - _data->idx = idx; - _data->next = _table[idx]; + _data->next = Table::table[idx]; _data->prev = nullptr; #ifdef DEBUG_ENABLED if (unlikely(debug_stringname)) { @@ -332,10 +321,10 @@ StringName::StringName(const String &p_name, bool p_static) { } #endif - if (_table[idx]) { - _table[idx]->prev = _data; + if (Table::table[idx]) { + Table::table[idx]->prev = _data; } - _table[idx] = _data; + Table::table[idx] = _data; } StringName StringName::search(const char *p_name) { @@ -347,14 +336,14 @@ StringName StringName::search(const char *p_name) { } const uint32_t hash = String::hash(p_name); - const uint32_t idx = hash & STRING_TABLE_MASK; + const uint32_t idx = hash & Table::TABLE_MASK; - MutexLock lock(mutex); - _Data *_data = _table[idx]; + MutexLock lock(Table::mutex); + _Data *_data = Table::table[idx]; while (_data) { // compare hash first - if (_data->hash == hash && _data->operator==(p_name)) { + if (_data->hash == hash && _data->name == p_name) { break; } _data = _data->next; @@ -382,14 +371,14 @@ StringName StringName::search(const char32_t *p_name) { } const uint32_t hash = String::hash(p_name); - const uint32_t idx = hash & STRING_TABLE_MASK; + const uint32_t idx = hash & Table::TABLE_MASK; - MutexLock lock(mutex); - _Data *_data = _table[idx]; + MutexLock lock(Table::mutex); + _Data *_data = Table::table[idx]; while (_data) { // compare hash first - if (_data->hash == hash && _data->operator==(p_name)) { + if (_data->hash == hash && _data->name == p_name) { break; } _data = _data->next; @@ -406,14 +395,14 @@ StringName StringName::search(const String &p_name) { ERR_FAIL_COND_V(p_name.is_empty(), StringName()); const uint32_t hash = p_name.hash(); - const uint32_t idx = hash & STRING_TABLE_MASK; + const uint32_t idx = hash & Table::TABLE_MASK; - MutexLock lock(mutex); - _Data *_data = _table[idx]; + MutexLock lock(Table::mutex); + _Data *_data = Table::table[idx]; while (_data) { // compare hash first - if (_data->hash == hash && _data->operator==(p_name)) { + if (_data->hash == hash && _data->name == p_name) { break; } _data = _data->next; diff --git a/core/string/string_name.h b/core/string/string_name.h index 996ef162643a..319c863e793c 100644 --- a/core/string/string_name.h +++ b/core/string/string_name.h @@ -39,11 +39,7 @@ class Main; class StringName { - enum { - STRING_TABLE_BITS = 16, - STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, - STRING_TABLE_MASK = STRING_TABLE_LEN - 1 - }; + struct Table; struct _Data { SafeRefCount refcount; @@ -52,28 +48,19 @@ class StringName { #ifdef DEBUG_ENABLED uint32_t debug_references = 0; #endif - const String &get_name() const { return name; } - bool operator==(const String &p_name) const; - bool operator!=(const String &p_name) const; - bool operator==(const char *p_name) const; - bool operator!=(const char *p_name) const; - int idx = 0; uint32_t hash = 0; _Data *prev = nullptr; _Data *next = nullptr; _Data() {} }; - static inline _Data *_table[STRING_TABLE_LEN]; - _Data *_data = nullptr; void unref(); friend void register_core_types(); friend void unregister_core_types(); friend class Main; - static inline Mutex mutex; static void setup(); static void cleanup(); static uint32_t get_empty_hash();