Просмотр исходного кода

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. :^)
Andreas Kling 4 лет назад
Родитель
Сommit
b7975abef8
2 измененных файлов с 9 добавлено и 3 удалено
  1. 8 3
      Libraries/LibJS/Runtime/Shape.cpp
  2. 1 0
      Libraries/LibJS/Runtime/Shape.h

+ 8 - 3
Libraries/LibJS/Runtime/Shape.cpp

@@ -38,6 +38,7 @@ Shape* Shape::create_unique_clone() const
     ensure_property_table();
     ensure_property_table();
     new_shape->ensure_property_table();
     new_shape->ensure_property_table();
     (*new_shape->m_property_table) = *m_property_table;
     (*new_shape->m_property_table) = *m_property_table;
+    new_shape->m_property_count = new_shape->m_property_table->size();
     return new_shape;
     return new_shape;
 }
 }
 
 
@@ -78,6 +79,7 @@ Shape::Shape(Shape& previous_shape, const StringOrSymbol& property_name, Propert
     , m_attributes(attributes)
     , m_attributes(attributes)
     , m_prototype(previous_shape.m_prototype)
     , m_prototype(previous_shape.m_prototype)
     , m_transition_type(transition_type)
     , 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_previous(&previous_shape)
     , m_prototype(new_prototype)
     , m_prototype(new_prototype)
     , m_transition_type(TransitionType::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
 size_t Shape::property_count() const
 {
 {
-    return property_table().size();
+    return m_property_count;
 }
 }
 
 
 Vector<Shape::Property> Shape::property_table_ordered() const
 Vector<Shape::Property> Shape::property_table_ordered() const
 {
 {
     auto vec = Vector<Shape::Property>();
     auto vec = Vector<Shape::Property>();
-    vec.resize(property_table().size());
+    vec.resize(property_count());
 
 
     for (auto& it : property_table()) {
     for (auto& it : property_table()) {
         vec[it.value.offset] = { it.key, it.value };
         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);
     ASSERT(!m_property_table->contains(property_name));
     ASSERT(!m_property_table->contains(property_name));
     m_property_table->set(property_name, { m_property_table->size(), attributes });
     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)
 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(is_unique());
     ASSERT(m_property_table);
     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) {
     for (auto& it : *m_property_table) {
         ASSERT(it.value.offset != offset);
         ASSERT(it.value.offset != offset);
         if (it.value.offset > offset)
         if (it.value.offset > offset)

+ 1 - 0
Libraries/LibJS/Runtime/Shape.h

@@ -112,6 +112,7 @@ private:
     bool m_unique { false };
     bool m_unique { false };
     Object* m_prototype { nullptr };
     Object* m_prototype { nullptr };
     TransitionType m_transition_type { TransitionType::Invalid };
     TransitionType m_transition_type { TransitionType::Invalid };
+    size_t m_property_count { 0 };
 };
 };
 
 
 }
 }