LibJS: Use OrderedHashMap for the Shape property table

This allows us to get rid of property_table_ordered() which was a
heavy-handed way of iterating properties in insertion order by first
copying them to a sorted Vector.

Clients can now simply iterate property_table() directly.

3% speed-up on Kraken/ai-astar.js :^)
This commit is contained in:
Andreas Kling 2023-09-17 11:29:43 +02:00
parent 8ce9e51c97
commit e33145aa4b
Notes: sideshowbarker 2024-07-16 23:54:15 +09:00
7 changed files with 13 additions and 27 deletions

View file

@ -123,7 +123,7 @@ ErrorOr<void> MarkupGenerator::object_to_html(Object const& object, StringBuilde
TRY(html_output.try_append(TRY(wrap_string_in_style(", "sv, StyleType::Punctuation))));
size_t index = 0;
for (auto& it : object.shape().property_table_ordered()) {
for (auto& it : object.shape().property_table()) {
TRY(html_output.try_append(TRY(wrap_string_in_style(TRY(String::formatted("\"{}\"", escape_html_entities(it.key.to_display_string()))), StyleType::String))));
TRY(html_output.try_append(TRY(wrap_string_in_style(": "sv, StyleType::Punctuation))));
TRY(value_to_html(object.get_direct(it.value.offset), html_output, seen_objects));

View file

@ -1027,7 +1027,7 @@ ThrowCompletionOr<MarkedVector<Value>> Object::internal_own_property_keys() cons
}
// 3. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_string()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));
@ -1035,7 +1035,7 @@ ThrowCompletionOr<MarkedVector<Value>> Object::internal_own_property_keys() cons
}
// 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_symbol()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));

View file

@ -136,29 +136,17 @@ Optional<PropertyMetadata> Shape::lookup(StringOrSymbol const& property_key) con
return property;
}
FLATTEN HashMap<StringOrSymbol, PropertyMetadata> const& Shape::property_table() const
FLATTEN OrderedHashMap<StringOrSymbol, PropertyMetadata> const& Shape::property_table() const
{
ensure_property_table();
return *m_property_table;
}
Vector<Shape::Property> Shape::property_table_ordered() const
{
auto vec = Vector<Shape::Property>();
vec.resize(property_count());
for (auto& it : property_table()) {
vec[it.value.offset] = { it.key, it.value };
}
return vec;
}
void Shape::ensure_property_table() const
{
if (m_property_table)
return;
m_property_table = make<HashMap<StringOrSymbol, PropertyMetadata>>();
m_property_table = make<OrderedHashMap<StringOrSymbol, PropertyMetadata>>();
u32 next_offset = 0;

View file

@ -65,7 +65,7 @@ public:
Object const* prototype() const { return m_prototype; }
Optional<PropertyMetadata> lookup(StringOrSymbol const&) const;
HashMap<StringOrSymbol, PropertyMetadata> const& property_table() const;
OrderedHashMap<StringOrSymbol, PropertyMetadata> const& property_table() const;
u32 property_count() const { return m_property_count; }
struct Property {
@ -73,8 +73,6 @@ public:
PropertyMetadata value;
};
Vector<Property> property_table_ordered() const;
void set_prototype_without_transition(Object* new_prototype) { m_prototype = new_prototype; }
void remove_property_from_unique_shape(StringOrSymbol const&, size_t offset);
@ -97,7 +95,7 @@ private:
NonnullGCPtr<Realm> m_realm;
mutable OwnPtr<HashMap<StringOrSymbol, PropertyMetadata>> m_property_table;
mutable OwnPtr<OrderedHashMap<StringOrSymbol, PropertyMetadata>> m_property_table;
OwnPtr<HashMap<TransitionKey, WeakPtr<Shape>>> m_forward_transitions;
OwnPtr<HashMap<GCPtr<Object>, WeakPtr<Shape>>> m_prototype_transitions;

View file

@ -162,7 +162,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
}
// 7. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_string()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));
@ -170,7 +170,7 @@ ThrowCompletionOr<MarkedVector<Value>> StringObject::internal_own_property_keys(
}
// 8. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_symbol()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));

View file

@ -395,7 +395,7 @@ public:
}
// 3. For each own property key P of O such that Type(P) is String and P is not an integer index, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_string()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));
@ -403,7 +403,7 @@ public:
}
// 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_symbol()) {
// a. Add P as the last element of keys.
keys.append(it.key.to_value(vm));

View file

@ -400,13 +400,13 @@ JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> LegacyPlatformObject::interna
}
// 4. For each P of Os own property keys that is a String, in ascending chronological order of property creation, append P to keys.
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_string())
keys.append(it.key.to_value(vm));
}
// 5. For each P of Os own property keys that is a Symbol, in ascending chronological order of property creation, append P to keys.
for (auto& it : shape().property_table_ordered()) {
for (auto& it : shape().property_table()) {
if (it.key.is_symbol())
keys.append(it.key.to_value(vm));
}