1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 22:58:12 +00:00

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
3 changed files with 8 additions and 0 deletions

View file

@ -41,6 +41,8 @@ PrimitiveString::~PrimitiveString()
PrimitiveString* js_string(Heap& heap, String string) 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)); return heap.allocate_without_global_object<PrimitiveString>(move(string));
} }

View file

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

View file

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