1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:07:35 +00:00

LibJS: Add basic monomorphic caching for PutById property access

This patch makes it possible for JS::Object::internal_set() to populate
a CacheablePropertyMetadata, and uses this to implement a basic
monomorphic cache for the most common form of property write access.
This commit is contained in:
Andreas Kling 2023-11-08 20:51:26 +01:00
parent 28118623f5
commit b1b2ca1485
28 changed files with 99 additions and 54 deletions

View file

@ -887,7 +887,7 @@ ThrowCompletionOr<Value> Object::internal_get(PropertyKey const& property_key, V
}
// 10.1.9 [[Set]] ( P, V, Receiver ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver
ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Value value, Value receiver)
ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Value value, Value receiver, CacheablePropertyMetadata* cacheable_metadata)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
@ -897,11 +897,11 @@ ThrowCompletionOr<bool> Object::internal_set(PropertyKey const& property_key, Va
auto own_descriptor = TRY(internal_get_own_property(property_key));
// 3. Return ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
return ordinary_set_with_own_descriptor(property_key, value, receiver, own_descriptor);
return ordinary_set_with_own_descriptor(property_key, value, receiver, own_descriptor, cacheable_metadata);
}
// 10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc ), https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor
ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey const& property_key, Value value, Value receiver, Optional<PropertyDescriptor> own_descriptor)
ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey const& property_key, Value value, Value receiver, Optional<PropertyDescriptor> own_descriptor, CacheablePropertyMetadata* cacheable_metadata)
{
VERIFY(property_key.is_valid());
VERIFY(!value.is_empty());
@ -957,6 +957,13 @@ ThrowCompletionOr<bool> Object::ordinary_set_with_own_descriptor(PropertyKey con
// iii. Let valueDesc be the PropertyDescriptor { [[Value]]: V }.
auto value_descriptor = PropertyDescriptor { .value = value };
if (cacheable_metadata && own_descriptor.has_value() && own_descriptor->property_offset.has_value()) {
*cacheable_metadata = CacheablePropertyMetadata {
.type = CacheablePropertyMetadata::Type::OwnProperty,
.property_offset = own_descriptor->property_offset.value(),
};
}
// iv. Return ? Receiver.[[DefineOwnProperty]](P, valueDesc).
return TRY(receiver.as_object().internal_define_own_property(property_key, value_descriptor));
}