mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 06:07:44 +00:00
LibJS: Stop making shapes unique
We previously had a concept of unique shapes, which meant that they couldn't be shared between multiple objects. Object shapes became unique in three situations: - They were the shape of the global object. - They had more than 100 properties added to them. - They had one or more properties deleted from them. Unfortunately, unique shapes presented an annoying problem for inline caches, and we added a "unique shape serial number" for being able to tell that a unique shape had been mutated. This patch gets rid of the concept of unique shapes, simplifying all the caching code, since inline caches can now simply perform a shape check and then we're good. To make this possible, we now have the concept of delete transitions, which occur when a property is deleted from a shape. Note that this patch by itself introduces a performance regression in some situtations, since we now create a lot more shapes, and marking their property keys can be very heavy. This will be addressed in a subsequent patch.
This commit is contained in:
parent
ef86cf4646
commit
3d92c26445
8 changed files with 63 additions and 214 deletions
|
@ -48,20 +48,17 @@ public:
|
|||
Put,
|
||||
Configure,
|
||||
Prototype,
|
||||
Delete,
|
||||
};
|
||||
|
||||
Shape* create_put_transition(StringOrSymbol const&, PropertyAttributes attributes);
|
||||
Shape* create_configure_transition(StringOrSymbol const&, PropertyAttributes attributes);
|
||||
Shape* create_prototype_transition(Object* new_prototype);
|
||||
[[nodiscard]] NonnullGCPtr<Shape> create_delete_transition(StringOrSymbol const&);
|
||||
|
||||
void add_property_without_transition(StringOrSymbol const&, PropertyAttributes);
|
||||
void add_property_without_transition(PropertyKey const&, PropertyAttributes);
|
||||
|
||||
bool is_unique() const { return m_unique; }
|
||||
static FlatPtr is_unique_offset() { return OFFSET_OF(Shape, m_unique); }
|
||||
|
||||
Shape* create_unique_clone() const;
|
||||
|
||||
Realm& realm() const { return m_realm; }
|
||||
|
||||
Object* prototype() { return m_prototype; }
|
||||
|
@ -78,22 +75,17 @@ public:
|
|||
|
||||
void set_prototype_without_transition(Object* new_prototype) { m_prototype = new_prototype; }
|
||||
|
||||
void remove_property_from_unique_shape(StringOrSymbol const&, size_t offset);
|
||||
void add_property_to_unique_shape(StringOrSymbol const&, PropertyAttributes attributes);
|
||||
void reconfigure_property_in_unique_shape(StringOrSymbol const& property_key, PropertyAttributes attributes);
|
||||
|
||||
[[nodiscard]] u64 unique_shape_serial_number() const { return m_unique_shape_serial_number; }
|
||||
static FlatPtr unique_shape_serial_number_offset() { return OFFSET_OF(Shape, m_unique_shape_serial_number); }
|
||||
|
||||
private:
|
||||
explicit Shape(Realm&);
|
||||
Shape(Shape& previous_shape, StringOrSymbol const& property_key, PropertyAttributes attributes, TransitionType);
|
||||
Shape(Shape& previous_shape, StringOrSymbol const& property_key, TransitionType);
|
||||
Shape(Shape& previous_shape, Object* new_prototype);
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
Shape* get_or_prune_cached_forward_transition(TransitionKey const&);
|
||||
Shape* get_or_prune_cached_prototype_transition(Object* prototype);
|
||||
[[nodiscard]] GCPtr<Shape> get_or_prune_cached_delete_transition(StringOrSymbol const&);
|
||||
|
||||
void ensure_property_table() const;
|
||||
|
||||
|
@ -103,6 +95,7 @@ private:
|
|||
|
||||
OwnPtr<HashMap<TransitionKey, WeakPtr<Shape>>> m_forward_transitions;
|
||||
OwnPtr<HashMap<GCPtr<Object>, WeakPtr<Shape>>> m_prototype_transitions;
|
||||
OwnPtr<HashMap<StringOrSymbol, WeakPtr<Shape>>> m_delete_transitions;
|
||||
GCPtr<Shape> m_previous;
|
||||
StringOrSymbol m_property_key;
|
||||
GCPtr<Object> m_prototype;
|
||||
|
@ -110,11 +103,6 @@ private:
|
|||
|
||||
PropertyAttributes m_attributes { 0 };
|
||||
TransitionType m_transition_type { TransitionType::Invalid };
|
||||
bool m_unique { false };
|
||||
|
||||
// Since unique shapes never change identity, inline caches use this incrementing serial number
|
||||
// to know whether its property table has been modified since last time we checked.
|
||||
u64 m_unique_shape_serial_number { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue