mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 04:09:13 +00:00
LibJS: Use premade shape when creating mapped arguments objects
Knocks out a 0.4% profile item on Speedometer 3.
This commit is contained in:
parent
ed5ad267c7
commit
e0b32b1863
Notes:
github-actions[bot]
2025-04-18 23:14:55 +00:00
Author: https://github.com/awesomekling
Commit: e0b32b1863
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4400
4 changed files with 25 additions and 5 deletions
|
@ -1101,13 +1101,13 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Nonnull
|
||||||
auto value = arguments[index];
|
auto value = arguments[index];
|
||||||
|
|
||||||
// b. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
|
// b. Perform ! CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val).
|
||||||
MUST(object->create_data_property_or_throw(index, value));
|
object->indexed_properties().put(index, value);
|
||||||
|
|
||||||
// c. Set index to index + 1.
|
// c. Set index to index + 1.
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
// 16. Perform ! DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
||||||
MUST(object->define_property_or_throw(vm.names.length, { .value = Value(length), .writable = true, .enumerable = false, .configurable = true }));
|
object->put_direct(realm.intrinsics().mapped_arguments_object_length_offset(), Value(length));
|
||||||
|
|
||||||
// 17. Let mappedNames be a new empty List.
|
// 17. Let mappedNames be a new empty List.
|
||||||
HashTable<FlyString> mapped_names;
|
HashTable<FlyString> mapped_names;
|
||||||
|
@ -1147,10 +1147,10 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Nonnull
|
||||||
|
|
||||||
// 20. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
// 20. Perform ! DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
||||||
auto array_prototype_values = realm.intrinsics().array_prototype_values_function();
|
auto array_prototype_values = realm.intrinsics().array_prototype_values_function();
|
||||||
MUST(object->define_property_or_throw(vm.well_known_symbol_iterator(), { .value = array_prototype_values, .writable = true, .enumerable = false, .configurable = true }));
|
object->put_direct(realm.intrinsics().mapped_arguments_object_well_known_symbol_iterator_offset(), array_prototype_values);
|
||||||
|
|
||||||
// 21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
// 21. Perform ! DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }).
|
||||||
MUST(object->define_property_or_throw(vm.names.callee, { .value = &function, .writable = true, .enumerable = false, .configurable = true }));
|
object->put_direct(realm.intrinsics().mapped_arguments_object_callee_offset(), Value(&function));
|
||||||
|
|
||||||
// 22. Return obj.
|
// 22. Return obj.
|
||||||
return object;
|
return object;
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace JS {
|
||||||
GC_DEFINE_ALLOCATOR(ArgumentsObject);
|
GC_DEFINE_ALLOCATOR(ArgumentsObject);
|
||||||
|
|
||||||
ArgumentsObject::ArgumentsObject(Realm& realm, Environment& environment)
|
ArgumentsObject::ArgumentsObject(Realm& realm, Environment& environment)
|
||||||
: Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype(), MayInterfereWithIndexedPropertyAccess::Yes)
|
: Object(realm.intrinsics().mapped_arguments_object_shape(), MayInterfereWithIndexedPropertyAccess::Yes)
|
||||||
, m_environment(environment)
|
, m_environment(environment)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,15 @@ void Intrinsics::initialize_intrinsics(Realm& realm)
|
||||||
m_unmapped_arguments_object_well_known_symbol_iterator_offset = m_unmapped_arguments_object_shape->lookup(StringOrSymbol(vm.well_known_symbol_iterator())).value().offset;
|
m_unmapped_arguments_object_well_known_symbol_iterator_offset = m_unmapped_arguments_object_shape->lookup(StringOrSymbol(vm.well_known_symbol_iterator())).value().offset;
|
||||||
m_unmapped_arguments_object_callee_offset = m_unmapped_arguments_object_shape->lookup(vm.names.callee.to_string_or_symbol()).value().offset;
|
m_unmapped_arguments_object_callee_offset = m_unmapped_arguments_object_shape->lookup(vm.names.callee.to_string_or_symbol()).value().offset;
|
||||||
|
|
||||||
|
m_mapped_arguments_object_shape = heap().allocate<Shape>(realm);
|
||||||
|
m_mapped_arguments_object_shape->set_prototype_without_transition(m_object_prototype);
|
||||||
|
m_mapped_arguments_object_shape->add_property_without_transition(vm.names.length, Attribute::Writable | Attribute::Configurable);
|
||||||
|
m_mapped_arguments_object_shape->add_property_without_transition(vm.well_known_symbol_iterator(), Attribute::Writable | Attribute::Configurable);
|
||||||
|
m_mapped_arguments_object_shape->add_property_without_transition(vm.names.callee, Attribute::Writable | Attribute::Configurable);
|
||||||
|
m_mapped_arguments_object_length_offset = m_mapped_arguments_object_shape->lookup(vm.names.length.to_string_or_symbol()).value().offset;
|
||||||
|
m_mapped_arguments_object_well_known_symbol_iterator_offset = m_mapped_arguments_object_shape->lookup(StringOrSymbol(vm.well_known_symbol_iterator())).value().offset;
|
||||||
|
m_mapped_arguments_object_callee_offset = m_mapped_arguments_object_shape->lookup(vm.names.callee.to_string_or_symbol()).value().offset;
|
||||||
|
|
||||||
// Normally Realm::create() takes care of this, but these are allocated via Heap::allocate().
|
// Normally Realm::create() takes care of this, but these are allocated via Heap::allocate().
|
||||||
m_function_prototype->initialize(realm);
|
m_function_prototype->initialize(realm);
|
||||||
m_object_prototype->initialize(realm);
|
m_object_prototype->initialize(realm);
|
||||||
|
@ -406,6 +415,7 @@ void Intrinsics::visit_edges(Visitor& visitor)
|
||||||
visitor.visit(m_normal_function_shape);
|
visitor.visit(m_normal_function_shape);
|
||||||
visitor.visit(m_native_function_shape);
|
visitor.visit(m_native_function_shape);
|
||||||
visitor.visit(m_unmapped_arguments_object_shape);
|
visitor.visit(m_unmapped_arguments_object_shape);
|
||||||
|
visitor.visit(m_mapped_arguments_object_shape);
|
||||||
visitor.visit(m_proxy_constructor);
|
visitor.visit(m_proxy_constructor);
|
||||||
visitor.visit(m_async_from_sync_iterator_prototype);
|
visitor.visit(m_async_from_sync_iterator_prototype);
|
||||||
visitor.visit(m_async_generator_prototype);
|
visitor.visit(m_async_generator_prototype);
|
||||||
|
|
|
@ -45,6 +45,11 @@ public:
|
||||||
[[nodiscard]] u32 unmapped_arguments_object_well_known_symbol_iterator_offset() const { return m_unmapped_arguments_object_well_known_symbol_iterator_offset; }
|
[[nodiscard]] u32 unmapped_arguments_object_well_known_symbol_iterator_offset() const { return m_unmapped_arguments_object_well_known_symbol_iterator_offset; }
|
||||||
[[nodiscard]] u32 unmapped_arguments_object_callee_offset() const { return m_unmapped_arguments_object_callee_offset; }
|
[[nodiscard]] u32 unmapped_arguments_object_callee_offset() const { return m_unmapped_arguments_object_callee_offset; }
|
||||||
|
|
||||||
|
[[nodiscard]] GC::Ref<Shape> mapped_arguments_object_shape() { return *m_mapped_arguments_object_shape; }
|
||||||
|
[[nodiscard]] u32 mapped_arguments_object_length_offset() const { return m_mapped_arguments_object_length_offset; }
|
||||||
|
[[nodiscard]] u32 mapped_arguments_object_well_known_symbol_iterator_offset() const { return m_mapped_arguments_object_well_known_symbol_iterator_offset; }
|
||||||
|
[[nodiscard]] u32 mapped_arguments_object_callee_offset() const { return m_mapped_arguments_object_callee_offset; }
|
||||||
|
|
||||||
[[nodiscard]] GC::Ref<Accessor> throw_type_error_accessor() { return *m_throw_type_error_accessor; }
|
[[nodiscard]] GC::Ref<Accessor> throw_type_error_accessor() { return *m_throw_type_error_accessor; }
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
|
||||||
|
@ -169,6 +174,11 @@ private:
|
||||||
u32 m_unmapped_arguments_object_well_known_symbol_iterator_offset { 0 };
|
u32 m_unmapped_arguments_object_well_known_symbol_iterator_offset { 0 };
|
||||||
u32 m_unmapped_arguments_object_callee_offset { 0 };
|
u32 m_unmapped_arguments_object_callee_offset { 0 };
|
||||||
|
|
||||||
|
GC::Ptr<Shape> m_mapped_arguments_object_shape;
|
||||||
|
u32 m_mapped_arguments_object_length_offset { 0 };
|
||||||
|
u32 m_mapped_arguments_object_well_known_symbol_iterator_offset { 0 };
|
||||||
|
u32 m_mapped_arguments_object_callee_offset { 0 };
|
||||||
|
|
||||||
GC::Ptr<Accessor> m_throw_type_error_accessor;
|
GC::Ptr<Accessor> m_throw_type_error_accessor;
|
||||||
|
|
||||||
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
|
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue