summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-10-02 01:36:57 +0200
committerAndreas Kling <kling@serenityos.org>2021-10-02 16:39:28 +0200
commitf290c59dd82b3ae59bdb7c10bd7026788b879b8d (patch)
treef8ff759da1f5096e4ff752611b2eef02f8e5cfb0 /Userland
parentba6e4c7ae1d4883385c8ba75a31c3b38fa90c615 (diff)
downloadserenity-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.cpp1
-rw-r--r--Userland/Libraries/LibJS/Runtime/PrimitiveString.cpp10
-rw-r--r--Userland/Libraries/LibJS/Runtime/VM.h3
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;