1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:48:11 +00:00

LibJS/Bytecode: Invalidate inline caches on unique shape mutation

Since we can't rely on shape identity (i.e its pointer address) for
unique shapes, give them a serial number that increments whenever a
mutation occurs.

Inline caches can then compare this serial number against what they
have seen before.
This commit is contained in:
Andreas Kling 2023-07-10 20:45:31 +02:00 committed by Linus Groh
parent 17d23e76e5
commit cf6792ec40
6 changed files with 38 additions and 5 deletions

View file

@ -546,7 +546,10 @@ static ThrowCompletionOr<void> get_by_id(Bytecode::Interpreter& interpreter, Ide
}
// OPTIMIZATION: If the shape of the object hasn't changed, we can use the cached property offset.
if (&base_obj->shape() == cache.shape) {
// NOTE: Unique shapes don't change identity, so we compare their serial numbers instead.
auto& shape = base_obj->shape();
if (&shape == cache.shape
&& (!shape.is_unique() || shape.unique_shape_serial_number() == cache.unique_shape_serial_number)) {
interpreter.accumulator() = base_obj->get_direct(cache.property_offset.value());
return {};
}
@ -555,11 +558,9 @@ static ThrowCompletionOr<void> get_by_id(Bytecode::Interpreter& interpreter, Ide
interpreter.accumulator() = TRY(base_obj->internal_get(name, this_value, &cacheable_metadata));
if (cacheable_metadata.type == CacheablePropertyMetadata::Type::OwnProperty) {
cache.shape = &base_obj->shape();
cache.shape = shape;
cache.property_offset = cacheable_metadata.property_offset.value();
} else {
cache.shape = nullptr;
cache.property_offset = {};
cache.unique_shape_serial_number = shape.unique_shape_serial_number();
}
return {};