LibJS: Let the VM cache an empty ("") PrimitiveString

Empty string is extremely common and we can avoid a lot of heap churn
by simply caching one in the VM. Primitive strings are immutable anyway
so there is no observable behavior change outside of fewer collections.
This commit is contained in:
Andreas Kling 2020-09-22 16:36:33 +02:00
parent d1b58ee9ad
commit 69bbf0285b
Notes: sideshowbarker 2024-07-19 02:16:32 +09:00
3 changed files with 8 additions and 0 deletions

View file

@ -41,6 +41,8 @@ PrimitiveString::~PrimitiveString()
PrimitiveString* js_string(Heap& heap, String string)
{
if (string.is_empty())
return &heap.vm().empty_string();
return heap.allocate_without_global_object<PrimitiveString>(move(string));
}

View file

@ -38,6 +38,7 @@ NonnullRefPtr<VM> VM::create()
VM::VM()
: m_heap(*this)
{
m_empty_string = m_heap.allocate_without_global_object<PrimitiveString>(String::empty());
#define __JS_ENUMERATE(SymbolName, snake_name) \
m_well_known_symbol_##snake_name = js_symbol(*this, "Symbol." #SymbolName, false);
JS_ENUMERATE_WELL_KNOWN_SYMBOLS
@ -86,6 +87,7 @@ VM::InterpreterExecutionScope::~InterpreterExecutionScope()
void VM::gather_roots(HashTable<Cell*>& roots)
{
roots.set(m_empty_string);
if (m_exception)
roots.set(m_exception);
for (auto* interpreter : m_interpreters)

View file

@ -71,6 +71,8 @@ public:
Symbol* get_global_symbol(const String& description);
PrimitiveString& empty_string() { return *m_empty_string; }
private:
VM();
@ -81,6 +83,8 @@ private:
HashMap<String, Symbol*> m_global_symbol_map;
PrimitiveString* m_empty_string { nullptr };
#define __JS_ENUMERATE(SymbolName, snake_name) \
Symbol* m_well_known_symbol_##snake_name { nullptr };
JS_ENUMERATE_WELL_KNOWN_SYMBOLS