From 212319b25e62b6199d78e40108c0dfed5f9961c0 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 8 Dec 2021 09:38:31 +0100 Subject: [PATCH] LibJS: Only allocate space for Object private elements if needed Most JavaScript objects don't have private elements, so this reduces the size of typical JS::Object instances by two pointers. --- Userland/Libraries/LibJS/Runtime/Object.cpp | 19 ++++++++++++++----- Userland/Libraries/LibJS/Runtime/Object.h | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index c38491fad8..72dbd86acc 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -470,7 +470,10 @@ ThrowCompletionOr Object::copy_data_properties(Value source, HashTable< // 7.3.26 PrivateElementFind ( O, P ), https://tc39.es/ecma262/#sec-privateelementfind PrivateElement* Object::private_element_find(PrivateName const& name) { - auto element = m_private_elements.find_if([&](auto const& element) { + if (!m_private_elements) + return nullptr; + + auto element = m_private_elements->find_if([&](auto const& element) { return element.key == name; }); @@ -485,7 +488,9 @@ ThrowCompletionOr Object::private_field_add(PrivateName const& name, Value { if (auto* entry = private_element_find(name); entry) return vm().throw_completion(global_object(), ErrorType::PrivateFieldAlreadyDeclared, name.description); - m_private_elements.empend(name, PrivateElement::Kind::Field, value); + if (!m_private_elements) + m_private_elements = make>(); + m_private_elements->empend(name, PrivateElement::Kind::Field, value); return {}; } @@ -495,7 +500,9 @@ ThrowCompletionOr Object::private_method_or_accessor_add(PrivateElement el VERIFY(element.kind == PrivateElement::Kind::Method || element.kind == PrivateElement::Kind::Accessor); if (auto* entry = private_element_find(element.key); entry) return vm().throw_completion(global_object(), ErrorType::PrivateFieldAlreadyDeclared, element.key.description); - m_private_elements.append(move(element)); + if (!m_private_elements) + m_private_elements = make>(); + m_private_elements->append(move(element)); return {}; } @@ -1187,8 +1194,10 @@ void Object::visit_edges(Cell::Visitor& visitor) visitor.visit(value); }); - for (auto& private_element : m_private_elements) - visitor.visit(private_element.value); + if (m_private_elements) { + for (auto& private_element : *m_private_elements) + visitor.visit(private_element.value); + } } // 7.1.1.1 OrdinaryToPrimitive ( O, hint ), https://tc39.es/ecma262/#sec-ordinarytoprimitive diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 8b8a08d76b..7395291b18 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -208,7 +208,7 @@ private: Shape* m_shape { nullptr }; Vector m_storage; IndexedProperties m_indexed_properties; - Vector m_private_elements; // [[PrivateElements]] + OwnPtr> m_private_elements; // [[PrivateElements]] }; }