From a4a2a887dc8ff9182c77bfad5bc2aef027c9b221 Mon Sep 17 00:00:00 2001 From: Exar04 Date: Mon, 13 Apr 2026 22:52:01 +0530 Subject: [PATCH] perf(array): add dense array fast-path for Array.prototype.unshift Signed-off-by: Exar04 --- core/engine/src/builtins/array/mod.rs | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/core/engine/src/builtins/array/mod.rs b/core/engine/src/builtins/array/mod.rs index acd695878ea..a5550a384aa 100644 --- a/core/engine/src/builtins/array/mod.rs +++ b/core/engine/src/builtins/array/mod.rs @@ -1291,6 +1291,48 @@ impl Array { .with_message("length + number of arguments exceeds the max safe integer limit") .into()); } + + if o.is_array() { + let mut o_borrow = o.borrow_mut(); + let props = &mut o_borrow.properties_mut().indexed_properties; + + let fast_path = match props { + IndexedProperties::DenseI32(dense) if dense.len() as u64 == len => { + let all_i32: Option> = + args.iter().map(JsValue::as_i32).collect(); + if let Some(items) = all_i32 { + dense.splice(0..0, items); + true + } else { + false + } + } + IndexedProperties::DenseF64(dense) if dense.len() as u64 == len => { + let all_f64: Option> = + args.iter().map(JsValue::as_number).collect(); + if let Some(items) = all_f64 { + dense.splice(0..0, items); + true + } else { + false + } + } + IndexedProperties::DenseElement(dense) if dense.len() as u64 == len => { + dense.splice(0..0, args.iter().cloned()); + true + } + _ => false, + }; + + drop(o_borrow); + + if fast_path { + let new_len = len + arg_count; + Self::set_length(&o, new_len, context)?; + return Ok(new_len.into()); + } + } + // b. Let k be len. let mut k = len; // c. Repeat, while k > 0,