diff --git a/src/util/symbol.cpp b/src/util/symbol.cpp index 36910a47b..d9530c06f 100644 --- a/src/util/symbol.cpp +++ b/src/util/symbol.cpp @@ -23,7 +23,7 @@ Revision History: #include "util/string_buffer.h" #include -static DECLARE_MUTEX(g_symbol_lock); + symbol symbol::m_dummy(TAG(void*, nullptr, 2)); const symbol symbol::null; @@ -34,11 +34,21 @@ const symbol symbol::null; class internal_symbol_table { region m_region; //!< Region used to store symbol strings. str_hashtable m_table; //!< Table of created symbol strings. + DECLARE_MUTEX(lock); + public: + internal_symbol_table() { + ALLOC_MUTEX(lock); + } + + ~internal_symbol_table() { + DEALLOC_MUTEX(lock); + } + char const * get_str(char const * d) { const char * result; - lock_guard lock(*g_symbol_lock); + lock_guard _lock(*lock); str_hashtable::entry * e; if (m_table.insert_if_not_there_core(d, e)) { // new entry @@ -60,30 +70,53 @@ public: } }; -static internal_symbol_table* g_symbol_table = nullptr; +struct internal_symbol_tables { + unsigned sz; + internal_symbol_table** tables; + + internal_symbol_tables(unsigned sz): sz(sz), tables(alloc_vect(sz)) { + for (unsigned i = 0; i < sz; ++i) { + tables[i] = alloc(internal_symbol_table); + } + } + ~internal_symbol_tables() { + for (unsigned i = 0; i < sz; ++i) { + dealloc(tables[i]); + } + dealloc_vect(tables, sz); + } + + char const * get_str(char const * d) { + auto* table = tables[string_hash(d, static_cast(strlen(d)), 251) % sz]; + return table->get_str(d); + } +}; + + +static internal_symbol_tables* g_symbol_tables = nullptr; void initialize_symbols() { - if (!g_symbol_table) { - ALLOC_MUTEX(g_symbol_lock); - g_symbol_table = alloc(internal_symbol_table); + if (!g_symbol_tables) { + unsigned num_tables = 2 * std::min((unsigned) std::thread::hardware_concurrency(), 64u); + g_symbol_tables = alloc(internal_symbol_tables, num_tables); + } } void finalize_symbols() { - DEALLOC_MUTEX(g_symbol_lock); - dealloc(g_symbol_table); - g_symbol_table = nullptr; + dealloc(g_symbol_tables); + g_symbol_tables = nullptr; } symbol::symbol(char const * d) { if (d == nullptr) m_data = nullptr; else - m_data = g_symbol_table->get_str(d); + m_data = g_symbol_tables->get_str(d); } symbol & symbol::operator=(char const * d) { - m_data = g_symbol_table->get_str(d); + m_data = g_symbol_tables->get_str(d); return *this; }