1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:47:35 +00:00

LibJS: Implement string concatenation using ropes

Instead of concatenating string data every time you add two strings
together in JavaScript, we now create a new PrimitiveString that points
to the two concatenated strings instead.

This turns concatenated strings into a tree structure that doesn't have
to be serialized until someone wants the characters in the string.

This *dramatically* reduces the peak memory footprint when running
the SunSpider benchmark (from ~6G to ~1G on my machine). It's also
significantly faster (1.39x) :^)
This commit is contained in:
Andreas Kling 2022-08-05 23:58:47 +02:00
parent cf62d08b2a
commit 64b29eb459
3 changed files with 172 additions and 59 deletions

View file

@ -17,6 +17,7 @@ namespace JS {
class PrimitiveString final : public Cell {
public:
explicit PrimitiveString(PrimitiveString&, PrimitiveString&);
explicit PrimitiveString(String);
explicit PrimitiveString(Utf16String);
virtual ~PrimitiveString();
@ -37,12 +38,20 @@ public:
private:
virtual StringView class_name() const override { return "PrimitiveString"sv; }
virtual void visit_edges(Cell::Visitor&) override;
void resolve_rope_if_needed() const;
mutable bool m_is_rope { false };
mutable bool m_has_utf8_string { false };
mutable bool m_has_utf16_string { false };
mutable PrimitiveString* m_left { nullptr };
mutable PrimitiveString* m_right { nullptr };
mutable String m_utf8_string;
mutable bool m_has_utf8_string { false };
mutable Utf16String m_utf16_string;
mutable bool m_has_utf16_string { false };
};
PrimitiveString* js_string(Heap&, Utf16View const&);
@ -54,4 +63,6 @@ PrimitiveString* js_string(VM&, Utf16String);
PrimitiveString* js_string(Heap&, String);
PrimitiveString* js_string(VM&, String);
PrimitiveString* js_rope_string(VM&, PrimitiveString&, PrimitiveString&);
}