mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibJS: Lazily instantiate "prototype" field on ECMAScriptFunctionObject
This field is rarely accessed but we were creating it for every single script function instantiated. It's a little awkward but the same optimization can be found in other engines, so it's nothing crazy. This avoids creating roughly 80,000 objects on my x.com home feed.
This commit is contained in:
committed by
Andreas Kling
parent
941336505c
commit
cbe75f8251
Notes:
github-actions[bot]
2025-12-17 18:51:45 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/cbe75f8251f Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/7167
@@ -176,10 +176,7 @@ void ECMAScriptFunctionObject::initialize(Realm& realm)
|
||||
if (!is_arrow_function() && kind() == FunctionKind::Normal) {
|
||||
put_direct(realm.intrinsics().normal_function_length_offset(), Value(function_length()));
|
||||
put_direct(realm.intrinsics().normal_function_name_offset(), m_name_string);
|
||||
|
||||
auto prototype = Object::create_with_premade_shape(realm.intrinsics().normal_function_prototype_shape());
|
||||
prototype->put_direct(realm.intrinsics().normal_function_prototype_constructor_offset(), this);
|
||||
put_direct(realm.intrinsics().normal_function_prototype_offset(), prototype);
|
||||
m_may_need_lazy_prototype_instantiation = true;
|
||||
} else {
|
||||
PropertyDescriptor length_descriptor { .value = Value(function_length()), .writable = false, .enumerable = false, .configurable = true };
|
||||
MUST(define_property_or_throw(vm.names.length, length_descriptor));
|
||||
@@ -641,4 +638,20 @@ Utf16String ECMAScriptFunctionObject::name_for_call_stack() const
|
||||
return m_name_string->utf16_string();
|
||||
}
|
||||
|
||||
ThrowCompletionOr<Optional<PropertyDescriptor>> ECMAScriptFunctionObject::internal_get_own_property(PropertyKey const& property_key) const
|
||||
{
|
||||
if (m_may_need_lazy_prototype_instantiation && property_key == vm().names.prototype) {
|
||||
auto& realm = *this->realm();
|
||||
auto metadata = shape().lookup(property_key);
|
||||
if (!metadata.has_value()) {
|
||||
auto prototype = Object::create_with_premade_shape(realm.intrinsics().normal_function_prototype_shape());
|
||||
prototype->put_direct(realm.intrinsics().normal_function_prototype_constructor_offset(), this);
|
||||
const_cast<ECMAScriptFunctionObject*>(this)->define_direct_property(vm().names.prototype, prototype, Attribute::Writable);
|
||||
}
|
||||
m_may_need_lazy_prototype_instantiation = false;
|
||||
}
|
||||
|
||||
return Base::internal_get_own_property(property_key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user