LibJS+LibWeb: Devirtualize may_interfere_with_indexed_property_access()

This commit is contained in:
iliadsh 2023-11-09 07:29:52 +00:00 committed by Andreas Kling
parent 7f501d4d8a
commit 89da731aa6
Notes: sideshowbarker 2024-07-17 02:59:43 +09:00
29 changed files with 51 additions and 61 deletions

View file

@ -2490,8 +2490,6 @@ private:
virtual JS::ThrowCompletionOr<bool> internal_set_prototype_of(JS::Object* prototype) override;
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
JS::Realm& m_realm; // [[Realm]]
};
)~~~");
@ -2511,7 +2509,7 @@ static void generate_named_properties_object_definitions(IDL::Interface const& i
#include <LibWeb/WebIDL/AbstractOperations.h>
@named_properties_class@::@named_properties_class@(JS::Realm& realm)
: JS::Object(realm, nullptr)
: JS::Object(realm, nullptr, MayInterfereWithIndexedPropertyAccess::Yes)
, m_realm(realm)
{
}

View file

@ -11,7 +11,7 @@
namespace JS {
ArgumentsObject::ArgumentsObject(Realm& realm, Environment& environment)
: Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype())
: Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype(), MayInterfereWithIndexedPropertyAccess::Yes)
, m_environment(environment)
{
}

View file

@ -27,8 +27,6 @@ public:
virtual ThrowCompletionOr<bool> internal_set(PropertyKey const&, Value value, Value receiver, CacheablePropertyMetadata*) override;
virtual ThrowCompletionOr<bool> internal_delete(PropertyKey const&) override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
// [[ParameterMap]]
Object& parameter_map() { return *m_parameter_map; }

View file

@ -13,13 +13,13 @@
namespace JS {
FunctionObject::FunctionObject(Realm& realm, Object* prototype)
: Object(realm, prototype)
FunctionObject::FunctionObject(Realm& realm, Object* prototype, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: Object(realm, prototype, may_interfere_with_indexed_property_access)
{
}
FunctionObject::FunctionObject(Object& prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype)
FunctionObject::FunctionObject(Object& prototype, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: Object(ConstructWithPrototypeTag::Tag, prototype, may_interfere_with_indexed_property_access)
{
}

View file

@ -41,8 +41,8 @@ public:
virtual Vector<DeprecatedFlyString> const& local_variables_names() const { VERIFY_NOT_REACHED(); }
protected:
explicit FunctionObject(Realm&, Object* prototype);
explicit FunctionObject(Object& prototype);
explicit FunctionObject(Realm&, Object* prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
explicit FunctionObject(Object& prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
private:
virtual bool is_function() const override { return true; }

View file

@ -11,7 +11,7 @@
namespace JS {
ModuleNamespaceObject::ModuleNamespaceObject(Realm& realm, Module* module, Vector<DeprecatedFlyString> exports)
: Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype())
: Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype(), MayInterfereWithIndexedPropertyAccess::Yes)
, m_module(module)
, m_exports(move(exports))
{

View file

@ -31,8 +31,6 @@ public:
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override;
virtual void initialize(Realm&) override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
private:
ModuleNamespaceObject(Realm&, Module* module, Vector<DeprecatedFlyString> exports);

View file

@ -35,18 +35,21 @@ NonnullGCPtr<Object> Object::create(Realm& realm, Object* prototype)
return realm.heap().allocate<Object>(realm, ConstructWithPrototypeTag::Tag, *prototype);
}
Object::Object(GlobalObjectTag, Realm& realm)
Object::Object(GlobalObjectTag, Realm& realm, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: m_may_interfere_with_indexed_property_access(may_interfere_with_indexed_property_access == MayInterfereWithIndexedPropertyAccess::Yes)
{
// This is the global object
m_shape = heap().allocate_without_realm<Shape>(realm);
}
Object::Object(ConstructWithoutPrototypeTag, Realm& realm)
Object::Object(ConstructWithoutPrototypeTag, Realm& realm, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: m_may_interfere_with_indexed_property_access(may_interfere_with_indexed_property_access == MayInterfereWithIndexedPropertyAccess::Yes)
{
m_shape = heap().allocate_without_realm<Shape>(realm);
}
Object::Object(Realm& realm, Object* prototype)
Object::Object(Realm& realm, Object* prototype, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: m_may_interfere_with_indexed_property_access(may_interfere_with_indexed_property_access == MayInterfereWithIndexedPropertyAccess::Yes)
{
m_shape = realm.intrinsics().empty_object_shape();
VERIFY(m_shape);
@ -54,15 +57,17 @@ Object::Object(Realm& realm, Object* prototype)
set_prototype(prototype);
}
Object::Object(ConstructWithPrototypeTag, Object& prototype)
Object::Object(ConstructWithPrototypeTag, Object& prototype, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: m_may_interfere_with_indexed_property_access(may_interfere_with_indexed_property_access == MayInterfereWithIndexedPropertyAccess::Yes)
{
m_shape = prototype.shape().realm().intrinsics().empty_object_shape();
VERIFY(m_shape);
set_prototype(&prototype);
}
Object::Object(Shape& shape)
: m_shape(&shape)
Object::Object(Shape& shape, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: m_may_interfere_with_indexed_property_access(may_interfere_with_indexed_property_access == MayInterfereWithIndexedPropertyAccess::Yes)
, m_shape(&shape)
{
m_storage.resize(shape.property_count());
}

View file

@ -76,6 +76,11 @@ public:
Yes,
};
enum class MayInterfereWithIndexedPropertyAccess {
No,
Yes,
};
// Please DO NOT make up your own non-standard methods unless you
// have a very good reason to do so. If any object abstract
// operation from the spec is missing, add it instead.
@ -139,7 +144,7 @@ public:
// to customize access to indexed properties (properties where the name is a positive integer)
// must return true for this, to opt out of optimizations that rely on assumptions that
// might not hold when property access behaves differently.
virtual bool may_interfere_with_indexed_property_access() const { return false; }
bool may_interfere_with_indexed_property_access() const { return m_may_interfere_with_indexed_property_access; }
ThrowCompletionOr<bool> ordinary_set_with_own_descriptor(PropertyKey const&, Value, Value, Optional<PropertyDescriptor>, CacheablePropertyMetadata* = nullptr);
@ -218,11 +223,11 @@ protected:
enum class ConstructWithoutPrototypeTag { Tag };
enum class ConstructWithPrototypeTag { Tag };
Object(GlobalObjectTag, Realm&);
Object(ConstructWithoutPrototypeTag, Realm&);
Object(Realm&, Object* prototype);
Object(ConstructWithPrototypeTag, Object& prototype);
explicit Object(Shape&);
Object(GlobalObjectTag, Realm&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
Object(ConstructWithoutPrototypeTag, Realm&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
Object(Realm&, Object* prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
Object(ConstructWithPrototypeTag, Object& prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
explicit Object(Shape&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
// [[Extensible]]
bool m_is_extensible { true };
@ -236,6 +241,8 @@ private:
Object* prototype() { return shape().prototype(); }
Object const* prototype() const { return shape().prototype(); }
bool m_may_interfere_with_indexed_property_access { false };
// True if this object has lazily allocated intrinsic properties.
bool m_has_intrinsic_accessors { false };

View file

@ -22,7 +22,7 @@ NonnullGCPtr<ProxyObject> ProxyObject::create(Realm& realm, Object& target, Obje
}
ProxyObject::ProxyObject(Object& target, Object& handler, Object& prototype)
: FunctionObject(prototype)
: FunctionObject(prototype, MayInterfereWithIndexedPropertyAccess::Yes)
, m_target(target)
, m_handler(handler)
{

View file

@ -45,8 +45,6 @@ public:
virtual ThrowCompletionOr<Value> internal_call(Value this_argument, MarkedVector<Value> arguments_list) override;
virtual ThrowCompletionOr<NonnullGCPtr<Object>> internal_construct(MarkedVector<Value> arguments_list, FunctionObject& new_target) override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
private:
ProxyObject(Object& target, Object& handler, Object& prototype);

View file

@ -30,7 +30,7 @@ NonnullGCPtr<StringObject> StringObject::create(Realm& realm, PrimitiveString& p
}
StringObject::StringObject(PrimitiveString& string, Object& prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype, MayInterfereWithIndexedPropertyAccess::Yes)
, m_string(string)
{
}

View file

@ -30,8 +30,6 @@ private:
virtual ThrowCompletionOr<bool> internal_define_own_property(PropertyKey const&, PropertyDescriptor const&) override;
virtual ThrowCompletionOr<MarkedVector<Value>> internal_own_property_keys() const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
virtual bool is_string_object() const final { return true; }
virtual void visit_edges(Visitor&) override;

View file

@ -459,7 +459,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor)
} \
\
PrototypeName::PrototypeName(Object& prototype) \
: Object(ConstructWithPrototypeTag::Tag, prototype) \
: Object(ConstructWithPrototypeTag::Tag, prototype, MayInterfereWithIndexedPropertyAccess::Yes) \
{ \
} \
\

View file

@ -62,7 +62,7 @@ public:
protected:
TypedArrayBase(Object& prototype, IntrinsicConstructor intrinsic_constructor)
: Object(ConstructWithPrototypeTag::Tag, prototype)
: Object(ConstructWithPrototypeTag::Tag, prototype, MayInterfereWithIndexedPropertyAccess::Yes)
, m_intrinsic_constructor(intrinsic_constructor)
{
}
@ -414,8 +414,6 @@ public:
return { move(keys) };
}
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
ReadonlySpan<UnderlyingBufferDataType> data() const
{
return { reinterpret_cast<UnderlyingBufferDataType const*>(m_viewed_array_buffer->buffer().data() + m_byte_offset), m_array_length };

View file

@ -12,7 +12,7 @@
namespace Web::Bindings {
LegacyPlatformObject::LegacyPlatformObject(JS::Realm& realm)
: PlatformObject(realm)
: PlatformObject(realm, MayInterfereWithIndexedPropertyAccess::Yes)
{
}

View file

@ -29,8 +29,6 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_prevent_extensions() override;
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
enum class IgnoreNamedProps {
No,
Yes,

View file

@ -11,13 +11,13 @@
namespace Web::Bindings {
PlatformObject::PlatformObject(JS::Realm& realm)
: JS::Object(realm, nullptr)
PlatformObject::PlatformObject(JS::Realm& realm, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: JS::Object(realm, nullptr, may_interfere_with_indexed_property_access)
{
}
PlatformObject::PlatformObject(JS::Object& prototype)
: JS::Object(ConstructWithPrototypeTag::Tag, prototype)
PlatformObject::PlatformObject(JS::Object& prototype, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: JS::Object(ConstructWithPrototypeTag::Tag, prototype, may_interfere_with_indexed_property_access)
{
}

View file

@ -40,8 +40,8 @@ public:
[[nodiscard]] virtual bool implements_interface(DeprecatedString const&) const { return false; }
protected:
explicit PlatformObject(JS::Realm&);
explicit PlatformObject(JS::Object& prototype);
explicit PlatformObject(JS::Realm&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
explicit PlatformObject(JS::Object& prototype, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
};
}

View file

@ -38,8 +38,8 @@
namespace Web::DOM {
EventTarget::EventTarget(JS::Realm& realm)
: PlatformObject(realm)
EventTarget::EventTarget(JS::Realm& realm, MayInterfereWithIndexedPropertyAccess may_interfere_with_indexed_property_access)
: PlatformObject(realm, may_interfere_with_indexed_property_access)
{
}

View file

@ -59,7 +59,7 @@ public:
bool has_event_listeners() const;
protected:
explicit EventTarget(JS::Realm&);
explicit EventTarget(JS::Realm&, MayInterfereWithIndexedPropertyAccess = MayInterfereWithIndexedPropertyAccess::No);
void element_event_handler_attribute_changed(FlyString const& local_name, Optional<String> const& value);

View file

@ -14,7 +14,7 @@
namespace Web::HTML {
AudioTrackList::AudioTrackList(JS::Realm& realm)
: DOM::EventTarget(realm)
: DOM::EventTarget(realm, MayInterfereWithIndexedPropertyAccess::Yes)
, m_audio_tracks(realm.heap())
{
}

View file

@ -51,8 +51,6 @@ private:
virtual void initialize(JS::Realm&) override;
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const& property_name) const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
JS::MarkedVector<JS::NonnullGCPtr<AudioTrack>> m_audio_tracks;
};

View file

@ -24,7 +24,7 @@ namespace Web::HTML {
// https://html.spec.whatwg.org/multipage/history.html#the-location-interface
Location::Location(JS::Realm& realm)
: PlatformObject(realm)
: PlatformObject(realm, MayInterfereWithIndexedPropertyAccess::Yes)
{
}

View file

@ -64,8 +64,6 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
HTML::CrossOriginPropertyDescriptorMap const& cross_origin_property_descriptor_map() const { return m_cross_origin_property_descriptor_map; }
HTML::CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; }

View file

@ -14,7 +14,7 @@
namespace Web::HTML {
VideoTrackList::VideoTrackList(JS::Realm& realm)
: DOM::EventTarget(realm)
: DOM::EventTarget(realm, MayInterfereWithIndexedPropertyAccess::Yes)
, m_video_tracks(realm.heap())
{
}

View file

@ -44,8 +44,6 @@ private:
virtual void initialize(JS::Realm&) override;
virtual JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> internal_get_own_property(JS::PropertyKey const& property_name) const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
JS::MarkedVector<JS::NonnullGCPtr<VideoTrack>> m_video_tracks;
};

View file

@ -22,7 +22,7 @@ namespace Web::HTML {
// 7.4 The WindowProxy exotic object, https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object
WindowProxy::WindowProxy(JS::Realm& realm)
: JS::Object(realm, nullptr)
: JS::Object(realm, nullptr, MayInterfereWithIndexedPropertyAccess::Yes)
{
}

View file

@ -31,8 +31,6 @@ public:
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
virtual bool may_interfere_with_indexed_property_access() const final { return true; }
JS::GCPtr<Window> window() const { return m_window; }
void set_window(JS::NonnullGCPtr<Window>);