summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-10-04 18:02:28 +0200
committerAndreas Kling <kling@serenityos.org>2020-10-04 19:25:49 +0200
commitb7975abef8eff6f6b3a609077c2fbf77a938aeca (patch)
treee58904a73a8f0e4a3f29268d1fda99aa67f77b64 /Libraries
parentd01b746d8810890250995084dcd7b97f870286b1 (diff)
downloadserenity-b7975abef8eff6f6b3a609077c2fbf77a938aeca.zip
LibJS: Don't force property table reification on Shape::property_count()
Previously whenever you would ask a Shape how many properties it had, it would reify the property table into a HashMap and use HashMap::size() to answer the question. This can be a huge waste of time if we don't need the property table for anything else, so this patch implements property count tracking in a separate integer member of Shape. :^)
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibJS/Runtime/Shape.cpp11
-rw-r--r--Libraries/LibJS/Runtime/Shape.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/Libraries/LibJS/Runtime/Shape.cpp b/Libraries/LibJS/Runtime/Shape.cpp
index e83dcd98d8..ecac57610e 100644
--- a/Libraries/LibJS/Runtime/Shape.cpp
+++ b/Libraries/LibJS/Runtime/Shape.cpp
@@ -38,6 +38,7 @@ Shape* Shape::create_unique_clone() const
ensure_property_table();
new_shape->ensure_property_table();
(*new_shape->m_property_table) = *m_property_table;
+ new_shape->m_property_count = new_shape->m_property_table->size();
return new_shape;
}
@@ -78,6 +79,7 @@ Shape::Shape(Shape& previous_shape, const StringOrSymbol& property_name, Propert
, m_attributes(attributes)
, m_prototype(previous_shape.m_prototype)
, m_transition_type(transition_type)
+ , m_property_count(transition_type == TransitionType::Put ? previous_shape.m_property_count + 1 : previous_shape.m_property_count)
{
}
@@ -86,6 +88,7 @@ Shape::Shape(Shape& previous_shape, Object* new_prototype)
, m_previous(&previous_shape)
, m_prototype(new_prototype)
, m_transition_type(TransitionType::Prototype)
+ , m_property_count(previous_shape.m_property_count)
{
}
@@ -125,13 +128,13 @@ const HashMap<StringOrSymbol, PropertyMetadata>& Shape::property_table() const
size_t Shape::property_count() const
{
- return property_table().size();
+ return m_property_count;
}
Vector<Shape::Property> Shape::property_table_ordered() const
{
auto vec = Vector<Shape::Property>();
- vec.resize(property_table().size());
+ vec.resize(property_count());
for (auto& it : property_table()) {
vec[it.value.offset] = { it.key, it.value };
@@ -176,6 +179,7 @@ void Shape::add_property_to_unique_shape(const StringOrSymbol& property_name, Pr
ASSERT(m_property_table);
ASSERT(!m_property_table->contains(property_name));
m_property_table->set(property_name, { m_property_table->size(), attributes });
+ ++m_property_count;
}
void Shape::reconfigure_property_in_unique_shape(const StringOrSymbol& property_name, PropertyAttributes attributes)
@@ -190,7 +194,8 @@ void Shape::remove_property_from_unique_shape(const StringOrSymbol& property_nam
{
ASSERT(is_unique());
ASSERT(m_property_table);
- m_property_table->remove(property_name);
+ if (m_property_table->remove(property_name))
+ --m_property_count;
for (auto& it : *m_property_table) {
ASSERT(it.value.offset != offset);
if (it.value.offset > offset)
diff --git a/Libraries/LibJS/Runtime/Shape.h b/Libraries/LibJS/Runtime/Shape.h
index 4e7f87391c..96717d1434 100644
--- a/Libraries/LibJS/Runtime/Shape.h
+++ b/Libraries/LibJS/Runtime/Shape.h
@@ -112,6 +112,7 @@ private:
bool m_unique { false };
Object* m_prototype { nullptr };
TransitionType m_transition_type { TransitionType::Invalid };
+ size_t m_property_count { 0 };
};
}