diff --git a/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Libraries/LibJS/Runtime/PrimitiveString.cpp index cbb58e3fd93..6325a912328 100644 --- a/Libraries/LibJS/Runtime/PrimitiveString.cpp +++ b/Libraries/LibJS/Runtime/PrimitiveString.cpp @@ -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(move(string)); } diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp index e35cd5cf98a..37c73418723 100644 --- a/Libraries/LibJS/Runtime/VM.cpp +++ b/Libraries/LibJS/Runtime/VM.cpp @@ -38,6 +38,7 @@ NonnullRefPtr VM::create() VM::VM() : m_heap(*this) { + m_empty_string = m_heap.allocate_without_global_object(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& roots) { + roots.set(m_empty_string); if (m_exception) roots.set(m_exception); for (auto* interpreter : m_interpreters) diff --git a/Libraries/LibJS/Runtime/VM.h b/Libraries/LibJS/Runtime/VM.h index 26de0457815..b0996434727 100644 --- a/Libraries/LibJS/Runtime/VM.h +++ b/Libraries/LibJS/Runtime/VM.h @@ -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 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