From d8ec97c85f0b9e805b99e08cd45d4c4c95510c56 Mon Sep 17 00:00:00 2001 From: Jason Williams <936006+jasonwilliams@users.noreply.github.com> Date: Sat, 2 Nov 2024 16:29:08 +0000 Subject: [PATCH] use with_capacity to reduce re-allocations fixes #3896 (#3961) * use with_capacity to reduce allocations * Update to use const generics over runtime param * add comment above with_capacity * - move OWN_PROPS - add profiling marks in more places * use const in trait instead --- core/engine/src/builtins/array/mod.rs | 3 +++ core/engine/src/builtins/array_buffer/mod.rs | 2 ++ .../src/builtins/array_buffer/shared.rs | 2 ++ .../engine/src/builtins/async_function/mod.rs | 2 ++ .../builtins/async_generator_function/mod.rs | 2 ++ core/engine/src/builtins/bigint/mod.rs | 2 ++ core/engine/src/builtins/boolean/mod.rs | 2 ++ core/engine/src/builtins/builder.rs | 12 +++++++---- core/engine/src/builtins/dataview/mod.rs | 2 ++ core/engine/src/builtins/date/mod.rs | 2 ++ core/engine/src/builtins/error/aggregate.rs | 2 ++ core/engine/src/builtins/error/eval.rs | 2 ++ core/engine/src/builtins/error/mod.rs | 2 ++ core/engine/src/builtins/error/range.rs | 2 ++ core/engine/src/builtins/error/reference.rs | 2 ++ core/engine/src/builtins/error/syntax.rs | 2 ++ core/engine/src/builtins/error/type.rs | 2 ++ core/engine/src/builtins/error/uri.rs | 2 ++ core/engine/src/builtins/function/mod.rs | 2 ++ .../src/builtins/generator_function/mod.rs | 2 ++ core/engine/src/builtins/intl/collator/mod.rs | 2 ++ .../src/builtins/intl/date_time_format.rs | 2 ++ .../src/builtins/intl/list_format/mod.rs | 2 ++ core/engine/src/builtins/intl/locale/mod.rs | 2 ++ .../src/builtins/intl/number_format/mod.rs | 2 ++ .../src/builtins/intl/plural_rules/mod.rs | 2 ++ .../engine/src/builtins/intl/segmenter/mod.rs | 2 ++ core/engine/src/builtins/map/mod.rs | 2 ++ core/engine/src/builtins/mod.rs | 7 +++++++ core/engine/src/builtins/number/mod.rs | 2 ++ core/engine/src/builtins/object/mod.rs | 2 ++ core/engine/src/builtins/promise/mod.rs | 2 ++ core/engine/src/builtins/proxy/mod.rs | 2 ++ core/engine/src/builtins/regexp/mod.rs | 2 ++ core/engine/src/builtins/set/mod.rs | 2 ++ core/engine/src/builtins/string/mod.rs | 2 ++ core/engine/src/builtins/symbol/mod.rs | 2 ++ .../src/builtins/temporal/duration/mod.rs | 2 ++ .../src/builtins/temporal/instant/mod.rs | 2 ++ .../src/builtins/temporal/plain_date/mod.rs | 2 ++ .../builtins/temporal/plain_date_time/mod.rs | 2 ++ .../builtins/temporal/plain_month_day/mod.rs | 2 ++ .../src/builtins/temporal/plain_time/mod.rs | 2 ++ .../builtins/temporal/plain_year_month/mod.rs | 2 ++ .../builtins/temporal/zoned_date_time/mod.rs | 2 ++ .../src/builtins/typed_array/builtin.rs | 2 ++ core/engine/src/builtins/typed_array/mod.rs | 2 ++ core/engine/src/builtins/weak/weak_ref.rs | 2 ++ core/engine/src/builtins/weak_map/mod.rs | 2 ++ core/engine/src/builtins/weak_set/mod.rs | 2 ++ core/engine/src/context/icu.rs | 3 +++ core/engine/src/context/mod.rs | 1 + core/engine/src/module/loader.rs | 2 ++ .../engine/src/object/shape/property_table.rs | 21 +++++++++++++++---- .../src/object/shape/shared_shape/mod.rs | 3 ++- core/engine/src/vm/mod.rs | 1 + 56 files changed, 138 insertions(+), 9 deletions(-) diff --git a/core/engine/src/builtins/array/mod.rs b/core/engine/src/builtins/array/mod.rs index 947f76d0ca..4eda932d08 100644 --- a/core/engine/src/builtins/array/mod.rs +++ b/core/engine/src/builtins/array/mod.rs @@ -190,6 +190,9 @@ impl BuiltInObject for Array { } impl BuiltInConstructor for Array { + const P: usize = 41; + const SP: usize = 5; + const LENGTH: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = diff --git a/core/engine/src/builtins/array_buffer/mod.rs b/core/engine/src/builtins/array_buffer/mod.rs index d5ea40ab55..7c2e319702 100644 --- a/core/engine/src/builtins/array_buffer/mod.rs +++ b/core/engine/src/builtins/array_buffer/mod.rs @@ -374,6 +374,8 @@ impl BuiltInObject for ArrayBuffer { } impl BuiltInConstructor for ArrayBuffer { + const P: usize = 9; + const SP: usize = 2; const LENGTH: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = diff --git a/core/engine/src/builtins/array_buffer/shared.rs b/core/engine/src/builtins/array_buffer/shared.rs index a9be40ce3d..d19eec5ed5 100644 --- a/core/engine/src/builtins/array_buffer/shared.rs +++ b/core/engine/src/builtins/array_buffer/shared.rs @@ -155,6 +155,8 @@ impl BuiltInObject for SharedArrayBuffer { impl BuiltInConstructor for SharedArrayBuffer { const LENGTH: usize = 1; + const P: usize = 6; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::shared_array_buffer; diff --git a/core/engine/src/builtins/async_function/mod.rs b/core/engine/src/builtins/async_function/mod.rs index f8db6134e9..2ff782af84 100644 --- a/core/engine/src/builtins/async_function/mod.rs +++ b/core/engine/src/builtins/async_function/mod.rs @@ -52,6 +52,8 @@ impl BuiltInObject for AsyncFunction { impl BuiltInConstructor for AsyncFunction { const LENGTH: usize = 1; + const P: usize = 1; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::async_function; diff --git a/core/engine/src/builtins/async_generator_function/mod.rs b/core/engine/src/builtins/async_generator_function/mod.rs index c0ca21b09e..01bb0539de 100644 --- a/core/engine/src/builtins/async_generator_function/mod.rs +++ b/core/engine/src/builtins/async_generator_function/mod.rs @@ -57,6 +57,8 @@ impl BuiltInObject for AsyncGeneratorFunction { impl BuiltInConstructor for AsyncGeneratorFunction { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::async_generator_function; diff --git a/core/engine/src/builtins/bigint/mod.rs b/core/engine/src/builtins/bigint/mod.rs index 947183afa5..65caaa84cf 100644 --- a/core/engine/src/builtins/bigint/mod.rs +++ b/core/engine/src/builtins/bigint/mod.rs @@ -65,6 +65,8 @@ impl BuiltInObject for BigInt { impl BuiltInConstructor for BigInt { const LENGTH: usize = 1; + const P: usize = 3; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::bigint; diff --git a/core/engine/src/builtins/boolean/mod.rs b/core/engine/src/builtins/boolean/mod.rs index b33525a023..bd0766a918 100644 --- a/core/engine/src/builtins/boolean/mod.rs +++ b/core/engine/src/builtins/boolean/mod.rs @@ -51,6 +51,8 @@ impl BuiltInObject for Boolean { impl BuiltInConstructor for Boolean { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::boolean; diff --git a/core/engine/src/builtins/builder.rs b/core/engine/src/builtins/builder.rs index 459a5104d9..5411a1888d 100644 --- a/core/engine/src/builtins/builder.rs +++ b/core/engine/src/builtins/builder.rs @@ -135,6 +135,9 @@ impl ApplyToObject for OrdinaryObject { fn apply_to(self, _: &JsObject) {} } +// The number of properties that are always present in a standard constructor. See build method +const OWN_PROPS: usize = 3; + /// Builder for creating built-in objects, like `Array`. /// /// The marker `ObjectType` restricts the methods that can be called depending on the @@ -528,6 +531,7 @@ impl<'ctx> BuiltInBuilder<'ctx, OrdinaryObject> { } impl<'ctx> BuiltInBuilder<'ctx, Callable> { + /// Create a new builder for a constructor function setting the properties ahead of time for optimizations (less reallocations) pub(crate) fn from_standard_constructor( realm: &'ctx Realm, ) -> BuiltInConstructorWithPrototype<'ctx> { @@ -537,11 +541,11 @@ impl<'ctx> BuiltInBuilder<'ctx, Callable> { function: SC::constructor, name: js_string!(SC::NAME), length: SC::LENGTH, - object_property_table: PropertyTableInner::default(), - object_storage: Vec::default(), + object_property_table: PropertyTableInner::with_capacity(SC::SP + OWN_PROPS), + object_storage: Vec::with_capacity(SC::SP + OWN_PROPS), object: constructor.constructor(), - prototype_property_table: PropertyTableInner::default(), - prototype_storage: Vec::default(), + prototype_property_table: PropertyTableInner::with_capacity(SC::P), + prototype_storage: Vec::with_capacity(SC::P), prototype: constructor.prototype(), __proto__: Some(realm.intrinsics().constructors().function().prototype()), inherits: Some(realm.intrinsics().constructors().object().prototype()), diff --git a/core/engine/src/builtins/dataview/mod.rs b/core/engine/src/builtins/dataview/mod.rs index a8a4eaf283..1c36146715 100644 --- a/core/engine/src/builtins/dataview/mod.rs +++ b/core/engine/src/builtins/dataview/mod.rs @@ -167,6 +167,8 @@ impl BuiltInObject for DataView { impl BuiltInConstructor for DataView { const LENGTH: usize = 1; + const P: usize = 24; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::data_view; diff --git a/core/engine/src/builtins/date/mod.rs b/core/engine/src/builtins/date/mod.rs index 13f5b5c577..9e255893e2 100644 --- a/core/engine/src/builtins/date/mod.rs +++ b/core/engine/src/builtins/date/mod.rs @@ -185,6 +185,8 @@ impl BuiltInObject for Date { impl BuiltInConstructor for Date { const LENGTH: usize = 7; + const P: usize = 47; + const SP: usize = 3; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::date; diff --git a/core/engine/src/builtins/error/aggregate.rs b/core/engine/src/builtins/error/aggregate.rs index 3dacfbcaab..ddde1683c1 100644 --- a/core/engine/src/builtins/error/aggregate.rs +++ b/core/engine/src/builtins/error/aggregate.rs @@ -52,6 +52,8 @@ impl BuiltInObject for AggregateError { impl BuiltInConstructor for AggregateError { const LENGTH: usize = 2; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::aggregate_error; diff --git a/core/engine/src/builtins/error/eval.rs b/core/engine/src/builtins/error/eval.rs index 88f6d21f0d..360638cc7f 100644 --- a/core/engine/src/builtins/error/eval.rs +++ b/core/engine/src/builtins/error/eval.rs @@ -54,6 +54,8 @@ impl BuiltInObject for EvalError { impl BuiltInConstructor for EvalError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::eval_error; diff --git a/core/engine/src/builtins/error/mod.rs b/core/engine/src/builtins/error/mod.rs index 343080137b..2e22e17904 100644 --- a/core/engine/src/builtins/error/mod.rs +++ b/core/engine/src/builtins/error/mod.rs @@ -154,6 +154,8 @@ impl BuiltInObject for Error { impl BuiltInConstructor for Error { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::error; diff --git a/core/engine/src/builtins/error/range.rs b/core/engine/src/builtins/error/range.rs index 15cf63d64f..37278ae826 100644 --- a/core/engine/src/builtins/error/range.rs +++ b/core/engine/src/builtins/error/range.rs @@ -52,6 +52,8 @@ impl BuiltInObject for RangeError { impl BuiltInConstructor for RangeError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::range_error; diff --git a/core/engine/src/builtins/error/reference.rs b/core/engine/src/builtins/error/reference.rs index f56f6b403a..a16c77c3db 100644 --- a/core/engine/src/builtins/error/reference.rs +++ b/core/engine/src/builtins/error/reference.rs @@ -51,6 +51,8 @@ impl BuiltInObject for ReferenceError { impl BuiltInConstructor for ReferenceError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::reference_error; diff --git a/core/engine/src/builtins/error/syntax.rs b/core/engine/src/builtins/error/syntax.rs index 70333aaa10..9ac489dc71 100644 --- a/core/engine/src/builtins/error/syntax.rs +++ b/core/engine/src/builtins/error/syntax.rs @@ -54,6 +54,8 @@ impl BuiltInObject for SyntaxError { impl BuiltInConstructor for SyntaxError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::syntax_error; diff --git a/core/engine/src/builtins/error/type.rs b/core/engine/src/builtins/error/type.rs index 364afba24d..c0e8397ca2 100644 --- a/core/engine/src/builtins/error/type.rs +++ b/core/engine/src/builtins/error/type.rs @@ -60,6 +60,8 @@ impl BuiltInObject for TypeError { impl BuiltInConstructor for TypeError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::type_error; diff --git a/core/engine/src/builtins/error/uri.rs b/core/engine/src/builtins/error/uri.rs index 36e6f275bc..113ccebea2 100644 --- a/core/engine/src/builtins/error/uri.rs +++ b/core/engine/src/builtins/error/uri.rs @@ -53,6 +53,8 @@ impl BuiltInObject for UriError { impl BuiltInConstructor for UriError { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::uri_error; diff --git a/core/engine/src/builtins/function/mod.rs b/core/engine/src/builtins/function/mod.rs index 8c4967e564..0ff46d988a 100644 --- a/core/engine/src/builtins/function/mod.rs +++ b/core/engine/src/builtins/function/mod.rs @@ -356,6 +356,8 @@ impl BuiltInObject for BuiltInFunctionObject { impl BuiltInConstructor for BuiltInFunctionObject { const LENGTH: usize = 1; + const P: usize = 7; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::function; diff --git a/core/engine/src/builtins/generator_function/mod.rs b/core/engine/src/builtins/generator_function/mod.rs index c4687f1b05..017b23c7bf 100644 --- a/core/engine/src/builtins/generator_function/mod.rs +++ b/core/engine/src/builtins/generator_function/mod.rs @@ -62,6 +62,8 @@ impl BuiltInObject for GeneratorFunction { impl BuiltInConstructor for GeneratorFunction { const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::generator_function; diff --git a/core/engine/src/builtins/intl/collator/mod.rs b/core/engine/src/builtins/intl/collator/mod.rs index ea700d78b9..24520950ef 100644 --- a/core/engine/src/builtins/intl/collator/mod.rs +++ b/core/engine/src/builtins/intl/collator/mod.rs @@ -188,6 +188,8 @@ impl BuiltInObject for Collator { impl BuiltInConstructor for Collator { const LENGTH: usize = 0; + const P: usize = 3; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::collator; diff --git a/core/engine/src/builtins/intl/date_time_format.rs b/core/engine/src/builtins/intl/date_time_format.rs index f6dca66bfc..69cd896d8c 100644 --- a/core/engine/src/builtins/intl/date_time_format.rs +++ b/core/engine/src/builtins/intl/date_time_format.rs @@ -82,6 +82,8 @@ impl BuiltInObject for DateTimeFormat { impl BuiltInConstructor for DateTimeFormat { const LENGTH: usize = 0; + const P: usize = 0; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::date_time_format; diff --git a/core/engine/src/builtins/intl/list_format/mod.rs b/core/engine/src/builtins/intl/list_format/mod.rs index 9da43f072d..2cf3133b16 100644 --- a/core/engine/src/builtins/intl/list_format/mod.rs +++ b/core/engine/src/builtins/intl/list_format/mod.rs @@ -83,6 +83,8 @@ impl BuiltInObject for ListFormat { impl BuiltInConstructor for ListFormat { const LENGTH: usize = 0; + const P: usize = 4; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::list_format; diff --git a/core/engine/src/builtins/intl/locale/mod.rs b/core/engine/src/builtins/intl/locale/mod.rs index b285eaab13..cbcaa67481 100644 --- a/core/engine/src/builtins/intl/locale/mod.rs +++ b/core/engine/src/builtins/intl/locale/mod.rs @@ -157,6 +157,8 @@ impl BuiltInObject for Locale { impl BuiltInConstructor for Locale { const LENGTH: usize = 1; + const P: usize = 14; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::locale; diff --git a/core/engine/src/builtins/intl/number_format/mod.rs b/core/engine/src/builtins/intl/number_format/mod.rs index 979c7b4ce4..395355d279 100644 --- a/core/engine/src/builtins/intl/number_format/mod.rs +++ b/core/engine/src/builtins/intl/number_format/mod.rs @@ -173,6 +173,8 @@ impl BuiltInObject for NumberFormat { impl BuiltInConstructor for NumberFormat { const LENGTH: usize = 0; + const P: usize = 3; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::number_format; diff --git a/core/engine/src/builtins/intl/plural_rules/mod.rs b/core/engine/src/builtins/intl/plural_rules/mod.rs index 03589c1958..4689feff4d 100644 --- a/core/engine/src/builtins/intl/plural_rules/mod.rs +++ b/core/engine/src/builtins/intl/plural_rules/mod.rs @@ -83,6 +83,8 @@ impl BuiltInObject for PluralRules { impl BuiltInConstructor for PluralRules { const LENGTH: usize = 0; + const P: usize = 4; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plural_rules; diff --git a/core/engine/src/builtins/intl/segmenter/mod.rs b/core/engine/src/builtins/intl/segmenter/mod.rs index e506073df2..2eeb7afbd3 100644 --- a/core/engine/src/builtins/intl/segmenter/mod.rs +++ b/core/engine/src/builtins/intl/segmenter/mod.rs @@ -119,6 +119,8 @@ impl BuiltInObject for Segmenter { impl BuiltInConstructor for Segmenter { const LENGTH: usize = 0; + const P: usize = 3; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::segmenter; diff --git a/core/engine/src/builtins/map/mod.rs b/core/engine/src/builtins/map/mod.rs index 40223620e8..1d075d5120 100644 --- a/core/engine/src/builtins/map/mod.rs +++ b/core/engine/src/builtins/map/mod.rs @@ -108,6 +108,8 @@ impl BuiltInObject for Map { impl BuiltInConstructor for Map { const LENGTH: usize = 0; + const P: usize = 11; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::map; diff --git a/core/engine/src/builtins/mod.rs b/core/engine/src/builtins/mod.rs index b9a738f059..3fbe2473a8 100644 --- a/core/engine/src/builtins/mod.rs +++ b/core/engine/src/builtins/mod.rs @@ -37,6 +37,7 @@ pub mod weak_set; mod builder; use boa_macros::js_str; +use boa_profiler::Profiler; use builder::BuiltInBuilder; #[cfg(feature = "annex-b")] @@ -157,6 +158,10 @@ pub(crate) trait BuiltInObject: IntrinsicObject { /// /// [built-in object]: https://tc39.es/ecma262/#sec-built-in-object pub(crate) trait BuiltInConstructor: BuiltInObject { + /// Const Generic `P` is the minimum storage capacity for the prototype's Property table. + const P: usize; + /// Const Generic `SP` is the minimum storage capacity for the object's Static Property table. + const SP: usize; /// The amount of arguments this function object takes. const LENGTH: usize; @@ -304,6 +309,8 @@ impl Realm { /// /// [spec]: https://tc39.es/ecma262/#sec-setdefaultglobalbindings pub(crate) fn set_default_global_bindings(context: &mut Context) -> JsResult<()> { + let _timer = + Profiler::global().start_event("Builtins::set_default_global_bindings", "Builtins"); let global_object = context.global_object(); global_object.define_property_or_throw( diff --git a/core/engine/src/builtins/number/mod.rs b/core/engine/src/builtins/number/mod.rs index 7334591278..1a6dc39aac 100644 --- a/core/engine/src/builtins/number/mod.rs +++ b/core/engine/src/builtins/number/mod.rs @@ -108,6 +108,8 @@ impl BuiltInObject for Number { impl BuiltInConstructor for Number { const LENGTH: usize = 1; + const P: usize = 6; + const SP: usize = 14; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::number; diff --git a/core/engine/src/builtins/object/mod.rs b/core/engine/src/builtins/object/mod.rs index d90a5bd06a..1f34fd4910 100644 --- a/core/engine/src/builtins/object/mod.rs +++ b/core/engine/src/builtins/object/mod.rs @@ -150,6 +150,8 @@ impl BuiltInObject for OrdinaryObject { impl BuiltInConstructor for OrdinaryObject { const LENGTH: usize = 1; + const P: usize = 11; + const SP: usize = 23; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::object; diff --git a/core/engine/src/builtins/promise/mod.rs b/core/engine/src/builtins/promise/mod.rs index f9e0fe4e08..223fe40b2c 100644 --- a/core/engine/src/builtins/promise/mod.rs +++ b/core/engine/src/builtins/promise/mod.rs @@ -381,6 +381,8 @@ impl BuiltInObject for Promise { impl BuiltInConstructor for Promise { const LENGTH: usize = 1; + const P: usize = 4; + const SP: usize = 9; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::promise; diff --git a/core/engine/src/builtins/proxy/mod.rs b/core/engine/src/builtins/proxy/mod.rs index 880838fdc9..f92daa30f1 100644 --- a/core/engine/src/builtins/proxy/mod.rs +++ b/core/engine/src/builtins/proxy/mod.rs @@ -106,6 +106,8 @@ impl BuiltInObject for Proxy { impl BuiltInConstructor for Proxy { const LENGTH: usize = 2; + const P: usize = 0; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::proxy; diff --git a/core/engine/src/builtins/regexp/mod.rs b/core/engine/src/builtins/regexp/mod.rs index beb782af1a..73c0f57ef2 100644 --- a/core/engine/src/builtins/regexp/mod.rs +++ b/core/engine/src/builtins/regexp/mod.rs @@ -177,6 +177,8 @@ impl BuiltInObject for RegExp { impl BuiltInConstructor for RegExp { const LENGTH: usize = 2; + const P: usize = 19; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::regexp; diff --git a/core/engine/src/builtins/set/mod.rs b/core/engine/src/builtins/set/mod.rs index c29fca4f4e..a78984b187 100644 --- a/core/engine/src/builtins/set/mod.rs +++ b/core/engine/src/builtins/set/mod.rs @@ -109,6 +109,8 @@ impl BuiltInObject for Set { impl BuiltInConstructor for Set { const LENGTH: usize = 0; + const P: usize = 11; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::set; diff --git a/core/engine/src/builtins/string/mod.rs b/core/engine/src/builtins/string/mod.rs index 7656c3a0cb..22bab2cb55 100644 --- a/core/engine/src/builtins/string/mod.rs +++ b/core/engine/src/builtins/string/mod.rs @@ -198,6 +198,8 @@ impl BuiltInObject for String { impl BuiltInConstructor for String { const LENGTH: usize = 1; + const P: usize = 36; + const SP: usize = 3; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::string; diff --git a/core/engine/src/builtins/symbol/mod.rs b/core/engine/src/builtins/symbol/mod.rs index ca18aee702..c0d915a873 100644 --- a/core/engine/src/builtins/symbol/mod.rs +++ b/core/engine/src/builtins/symbol/mod.rs @@ -186,6 +186,8 @@ impl BuiltInObject for Symbol { impl BuiltInConstructor for Symbol { const LENGTH: usize = 0; + const P: usize = 5; + const SP: usize = 15; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::symbol; diff --git a/core/engine/src/builtins/temporal/duration/mod.rs b/core/engine/src/builtins/temporal/duration/mod.rs index 822e2c6c52..b302de2c73 100644 --- a/core/engine/src/builtins/temporal/duration/mod.rs +++ b/core/engine/src/builtins/temporal/duration/mod.rs @@ -201,6 +201,8 @@ impl IntrinsicObject for Duration { impl BuiltInConstructor for Duration { const LENGTH: usize = 0; + const P: usize = 22; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::duration; diff --git a/core/engine/src/builtins/temporal/instant/mod.rs b/core/engine/src/builtins/temporal/instant/mod.rs index f244e1f86c..771e0011d9 100644 --- a/core/engine/src/builtins/temporal/instant/mod.rs +++ b/core/engine/src/builtins/temporal/instant/mod.rs @@ -127,6 +127,8 @@ impl IntrinsicObject for Instant { impl BuiltInConstructor for Instant { const LENGTH: usize = 1; + const P: usize = 13; + const SP: usize = 4; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::instant; diff --git a/core/engine/src/builtins/temporal/plain_date/mod.rs b/core/engine/src/builtins/temporal/plain_date/mod.rs index 77f05f5b0d..345493d974 100644 --- a/core/engine/src/builtins/temporal/plain_date/mod.rs +++ b/core/engine/src/builtins/temporal/plain_date/mod.rs @@ -241,6 +241,8 @@ impl IntrinsicObject for PlainDate { impl BuiltInConstructor for PlainDate { const LENGTH: usize = 3; + const P: usize = 26; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plain_date; diff --git a/core/engine/src/builtins/temporal/plain_date_time/mod.rs b/core/engine/src/builtins/temporal/plain_date_time/mod.rs index a2a582754d..e296e570ee 100644 --- a/core/engine/src/builtins/temporal/plain_date_time/mod.rs +++ b/core/engine/src/builtins/temporal/plain_date_time/mod.rs @@ -298,6 +298,8 @@ impl IntrinsicObject for PlainDateTime { impl BuiltInConstructor for PlainDateTime { const LENGTH: usize = 3; + const P: usize = 29; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plain_date_time; diff --git a/core/engine/src/builtins/temporal/plain_month_day/mod.rs b/core/engine/src/builtins/temporal/plain_month_day/mod.rs index 37ad9f8ae6..bb49efdb28 100644 --- a/core/engine/src/builtins/temporal/plain_month_day/mod.rs +++ b/core/engine/src/builtins/temporal/plain_month_day/mod.rs @@ -185,6 +185,8 @@ impl IntrinsicObject for PlainMonthDay { impl BuiltInConstructor for PlainMonthDay { const LENGTH: usize = 2; + const P: usize = 5; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plain_month_day; diff --git a/core/engine/src/builtins/temporal/plain_time/mod.rs b/core/engine/src/builtins/temporal/plain_time/mod.rs index 18b1372539..c99461be48 100644 --- a/core/engine/src/builtins/temporal/plain_time/mod.rs +++ b/core/engine/src/builtins/temporal/plain_time/mod.rs @@ -129,6 +129,8 @@ impl IntrinsicObject for PlainTime { impl BuiltInConstructor for PlainTime { const LENGTH: usize = 0; + const P: usize = 15; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plain_time; diff --git a/core/engine/src/builtins/temporal/plain_year_month/mod.rs b/core/engine/src/builtins/temporal/plain_year_month/mod.rs index 74c90bd9c1..0cea51490c 100644 --- a/core/engine/src/builtins/temporal/plain_year_month/mod.rs +++ b/core/engine/src/builtins/temporal/plain_year_month/mod.rs @@ -167,6 +167,8 @@ impl IntrinsicObject for PlainYearMonth { impl BuiltInConstructor for PlainYearMonth { const LENGTH: usize = 2; + const P: usize = 16; + const SP: usize = 1; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::plain_year_month; diff --git a/core/engine/src/builtins/temporal/zoned_date_time/mod.rs b/core/engine/src/builtins/temporal/zoned_date_time/mod.rs index ee76c047e0..5f8e5e1678 100644 --- a/core/engine/src/builtins/temporal/zoned_date_time/mod.rs +++ b/core/engine/src/builtins/temporal/zoned_date_time/mod.rs @@ -42,6 +42,8 @@ impl IntrinsicObject for ZonedDateTime { impl BuiltInConstructor for ZonedDateTime { const LENGTH: usize = 2; + const P: usize = 1; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::zoned_date_time; diff --git a/core/engine/src/builtins/typed_array/builtin.rs b/core/engine/src/builtins/typed_array/builtin.rs index cde663cd6e..f4d34b2bd2 100644 --- a/core/engine/src/builtins/typed_array/builtin.rs +++ b/core/engine/src/builtins/typed_array/builtin.rs @@ -165,6 +165,8 @@ impl BuiltInObject for BuiltinTypedArray { impl BuiltInConstructor for BuiltinTypedArray { const LENGTH: usize = 0; + const P: usize = 37; + const SP: usize = 3; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::typed_array; diff --git a/core/engine/src/builtins/typed_array/mod.rs b/core/engine/src/builtins/typed_array/mod.rs index 168464d25e..41f6e93d82 100644 --- a/core/engine/src/builtins/typed_array/mod.rs +++ b/core/engine/src/builtins/typed_array/mod.rs @@ -94,6 +94,8 @@ impl BuiltInObject for T { impl BuiltInConstructor for T { const LENGTH: usize = 3; + const P: usize = 1; + const SP: usize = 2; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = ::ERASED.standard_constructor(); diff --git a/core/engine/src/builtins/weak/weak_ref.rs b/core/engine/src/builtins/weak/weak_ref.rs index a19ec15a7c..26cc460676 100644 --- a/core/engine/src/builtins/weak/weak_ref.rs +++ b/core/engine/src/builtins/weak/weak_ref.rs @@ -53,6 +53,8 @@ impl BuiltInObject for WeakRef { impl BuiltInConstructor for WeakRef { /// The amount of arguments the `WeakRef` constructor takes. const LENGTH: usize = 1; + const P: usize = 2; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::weak_ref; diff --git a/core/engine/src/builtins/weak_map/mod.rs b/core/engine/src/builtins/weak_map/mod.rs index dced501b8b..c326a56383 100644 --- a/core/engine/src/builtins/weak_map/mod.rs +++ b/core/engine/src/builtins/weak_map/mod.rs @@ -60,6 +60,8 @@ impl BuiltInObject for WeakMap { impl BuiltInConstructor for WeakMap { /// The amount of arguments the `WeakMap` constructor takes. const LENGTH: usize = 0; + const P: usize = 5; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::weak_map; diff --git a/core/engine/src/builtins/weak_set/mod.rs b/core/engine/src/builtins/weak_set/mod.rs index 4d19526bf0..b992267716 100644 --- a/core/engine/src/builtins/weak_set/mod.rs +++ b/core/engine/src/builtins/weak_set/mod.rs @@ -58,6 +58,8 @@ impl BuiltInObject for WeakSet { impl BuiltInConstructor for WeakSet { /// The amount of arguments the `WeakSet` constructor takes. const LENGTH: usize = 0; + const P: usize = 4; + const SP: usize = 0; const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor = StandardConstructors::weak_set; diff --git a/core/engine/src/context/icu.rs b/core/engine/src/context/icu.rs index 57a7b909f8..3c05b101a4 100644 --- a/core/engine/src/context/icu.rs +++ b/core/engine/src/context/icu.rs @@ -1,5 +1,6 @@ use std::{cell::OnceCell, fmt::Debug}; +use boa_profiler::Profiler; use icu_casemap::CaseMapper; use icu_locid_transform::{LocaleCanonicalizer, LocaleExpander, LocaleTransformError}; use icu_normalizer::{ComposingNormalizer, DecomposingNormalizer, NormalizerError}; @@ -89,6 +90,7 @@ impl IntlProvider { pub(crate) fn try_new_with_buffer_provider( provider: (impl BufferProvider + 'static), ) -> IntlProvider { + let _timer = Profiler::global().start_event("ICU::try_new_with_buffer_provider", "ICU"); Self { locale_canonicalizer: OnceCell::new(), locale_expander: OnceCell::new(), @@ -106,6 +108,7 @@ impl IntlProvider { pub(crate) fn try_new_with_any_provider( provider: (impl AnyProvider + 'static), ) -> IntlProvider { + let _timer = Profiler::global().start_event("ICU::try_new_with_any_provider", "ICU"); Self { locale_canonicalizer: OnceCell::new(), locale_expander: OnceCell::new(), diff --git a/core/engine/src/context/mod.rs b/core/engine/src/context/mod.rs index dd27ebf8f6..4ab70c3ac2 100644 --- a/core/engine/src/context/mod.rs +++ b/core/engine/src/context/mod.rs @@ -1052,6 +1052,7 @@ impl ContextBuilder { // TODO: try to use a custom error here, since most of the `JsError` APIs // require having a `Context` in the first place. pub fn build(self) -> JsResult { + let _timer = Profiler::global().start_event("Ctx::build", "context"); if self.can_block { if CANNOT_BLOCK_COUNTER.get() > 0 { return Err(JsNativeError::typ() diff --git a/core/engine/src/module/loader.rs b/core/engine/src/module/loader.rs index 8a90fab679..a4dd22ddbc 100644 --- a/core/engine/src/module/loader.rs +++ b/core/engine/src/module/loader.rs @@ -1,5 +1,6 @@ use std::path::{Component, Path, PathBuf}; +use boa_profiler::Profiler; use rustc_hash::FxHashMap; use boa_gc::GcRefCell; @@ -251,6 +252,7 @@ pub struct SimpleModuleLoader { impl SimpleModuleLoader { /// Creates a new `SimpleModuleLoader` from a root module path. pub fn new>(root: P) -> JsResult { + let _timer = Profiler::global().start_event("Loader::new", "Loader"); if cfg!(target_family = "wasm") { return Err(JsNativeError::typ() .with_message("cannot resolve a relative path in WASM targets") diff --git a/core/engine/src/object/shape/property_table.rs b/core/engine/src/object/shape/property_table.rs index cb2d751304..9aaa8f72dd 100644 --- a/core/engine/src/object/shape/property_table.rs +++ b/core/engine/src/object/shape/property_table.rs @@ -1,11 +1,9 @@ -use std::{cell::RefCell, rc::Rc}; - -use rustc_hash::FxHashMap; - use crate::{ object::shape::slot::{Slot, SlotAttributes}, property::PropertyKey, }; +use rustc_hash::{FxBuildHasher, FxHashMap}; +use std::{cell::RefCell, rc::Rc}; /// The internal representation of [`PropertyTable`]. #[derive(Default, Debug, Clone)] @@ -15,6 +13,14 @@ pub(crate) struct PropertyTableInner { } impl PropertyTableInner { + /// Returns a new table with a given minimum capacity. + pub(crate) fn with_capacity(capacity: usize) -> Self { + Self { + map: FxHashMap::with_capacity_and_hasher(capacity, FxBuildHasher), + keys: Vec::with_capacity(capacity), + } + } + /// Returns all the keys, in insertion order. pub(crate) fn keys(&self) -> Vec { self.keys_cloned_n(self.keys.len() as u32) @@ -74,6 +80,13 @@ pub(crate) struct PropertyTable { } impl PropertyTable { + /// Creates a new `PropertyTable` with the specified capacity. + pub(crate) fn with_capacity(capacity: usize) -> Self { + Self { + inner: Rc::new(RefCell::new(PropertyTableInner::with_capacity(capacity))), + } + } + /// Returns the inner representation of a [`PropertyTable`]. pub(super) fn inner(&self) -> &RefCell { &self.inner diff --git a/core/engine/src/object/shape/shared_shape/mod.rs b/core/engine/src/object/shape/shared_shape/mod.rs index b27b5f6200..3189603df1 100644 --- a/core/engine/src/object/shape/shared_shape/mod.rs +++ b/core/engine/src/object/shape/shared_shape/mod.rs @@ -186,7 +186,8 @@ impl SharedShape { forward_transitions: ForwardTransition::default(), prototype: None, property_count: 0, - property_table: PropertyTable::default(), + // Most of the time the root shape initiates with between 1-4 properties. + property_table: PropertyTable::with_capacity(4), previous: None, flags: ShapeFlags::default(), transition_count: 0, diff --git a/core/engine/src/vm/mod.rs b/core/engine/src/vm/mod.rs index 4e17a00121..ea4f019cd1 100644 --- a/core/engine/src/vm/mod.rs +++ b/core/engine/src/vm/mod.rs @@ -110,6 +110,7 @@ unsafe impl Trace for ActiveRunnable { impl Vm { /// Creates a new virtual machine. pub(crate) fn new(realm: Realm) -> Self { + let _timer = Profiler::global().start_event("VM::new", "VM"); Self { frames: Vec::with_capacity(16), frame: CallFrame::new(