diff options
author | Andreas Kling <kling@serenityos.org> | 2021-10-02 01:36:57 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-02 16:39:28 +0200 |
commit | f290c59dd82b3ae59bdb7c10bd7026788b879b8d (patch) | |
tree | f8ff759da1f5096e4ff752611b2eef02f8e5cfb0 /Userland | |
parent | ba6e4c7ae1d4883385c8ba75a31c3b38fa90c615 (diff) | |
download | serenity-f290c59dd82b3ae59bdb7c10bd7026788b879b8d.zip |
LibJS: Keep track of PrimitiveStrings and share them
VM now has a string cache which tracks all live PrimitiveStrings and
reuses an existing one if possible. This drastically reduces the number
of GC-allocated strings in many real-word situations.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibJS/Heap/Heap.cpp | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/VM.h | 3 |
3 files changed, 13 insertions, 1 deletions
diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index 48df49c432..5db59c29b4 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -52,6 +52,7 @@ Heap::Heap(VM& vm) Heap::~Heap() { + vm().string_cache().clear(); collect_garbage(CollectionType::CollectEverything); } diff --git a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp index 17c947c349..063c518f4a 100644 --- a/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp +++ b/Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp @@ -25,6 +25,7 @@ PrimitiveString::PrimitiveString(Utf16String string) PrimitiveString::~PrimitiveString() { + vm().string_cache().remove(m_utf8_string); } String const& PrimitiveString::string() const @@ -90,7 +91,14 @@ PrimitiveString* js_string(Heap& heap, String string) return &heap.vm().single_ascii_character_string(ch); } - return heap.allocate_without_global_object<PrimitiveString>(move(string)); + auto& string_cache = heap.vm().string_cache(); + auto it = string_cache.find(string); + if (it == string_cache.end()) { + auto* new_string = heap.allocate_without_global_object<PrimitiveString>(string); + string_cache.set(move(string), new_string); + return new_string; + } + return it->value; } PrimitiveString* js_string(VM& vm, String string) diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 216662fa40..b6d67206d0 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -81,6 +81,7 @@ public: Symbol* get_global_symbol(const String& description); + HashMap<String, PrimitiveString*>& string_cache() { return m_string_cache; } PrimitiveString& empty_string() { return *m_empty_string; } PrimitiveString& single_ascii_character_string(u8 character) { @@ -294,6 +295,8 @@ private: Exception* m_exception { nullptr }; + HashMap<String, PrimitiveString*> m_string_cache; + Heap m_heap; Vector<Interpreter*> m_interpreters; |