1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 16:18:12 +00:00

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
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)))); TRY(html_output.try_append(TRY(wrap_string_in_style(", "sv, StyleType::Punctuation))));
size_t index = 0; 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(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(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)); 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 // 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()) { if (it.key.is_string()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); 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 // 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()) { if (it.key.is_symbol()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); keys.append(it.key.to_value(vm));

View file

@ -136,29 +136,17 @@ Optional<PropertyMetadata> Shape::lookup(StringOrSymbol const& property_key) con
return property; return property;
} }
FLATTEN HashMap<StringOrSymbol, PropertyMetadata> const& Shape::property_table() const FLATTEN OrderedHashMap<StringOrSymbol, PropertyMetadata> const& Shape::property_table() const
{ {
ensure_property_table(); ensure_property_table();
return *m_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 void Shape::ensure_property_table() const
{ {
if (m_property_table) if (m_property_table)
return; return;
m_property_table = make<HashMap<StringOrSymbol, PropertyMetadata>>(); m_property_table = make<OrderedHashMap<StringOrSymbol, PropertyMetadata>>();
u32 next_offset = 0; u32 next_offset = 0;

View file

@ -65,7 +65,7 @@ public:
Object const* prototype() const { return m_prototype; } Object const* prototype() const { return m_prototype; }
Optional<PropertyMetadata> lookup(StringOrSymbol const&) const; 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; } u32 property_count() const { return m_property_count; }
struct Property { struct Property {
@ -73,8 +73,6 @@ public:
PropertyMetadata value; PropertyMetadata value;
}; };
Vector<Property> property_table_ordered() const;
void set_prototype_without_transition(Object* new_prototype) { m_prototype = new_prototype; } void set_prototype_without_transition(Object* new_prototype) { m_prototype = new_prototype; }
void remove_property_from_unique_shape(StringOrSymbol const&, size_t offset); void remove_property_from_unique_shape(StringOrSymbol const&, size_t offset);
@ -97,7 +95,7 @@ private:
NonnullGCPtr<Realm> m_realm; 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<TransitionKey, WeakPtr<Shape>>> m_forward_transitions;
OwnPtr<HashMap<GCPtr<Object>, WeakPtr<Shape>>> m_prototype_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 // 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()) { if (it.key.is_string()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); 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 // 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()) { if (it.key.is_symbol()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); 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 // 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()) { if (it.key.is_string()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); 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 // 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()) { if (it.key.is_symbol()) {
// a. Add P as the last element of keys. // a. Add P as the last element of keys.
keys.append(it.key.to_value(vm)); 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. // 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()) if (it.key.is_string())
keys.append(it.key.to_value(vm)); 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. // 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()) if (it.key.is_symbol())
keys.append(it.key.to_value(vm)); keys.append(it.key.to_value(vm));
} }