Skip to content

Commit d17cde1

Browse files
committed
Keep default array properties dense
1 parent 8265d8f commit d17cde1

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

crates/qjs-runtime/src/object/descriptor.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,14 @@ pub(crate) fn define_property_on_value_key(
753753
elements.set_len(crate::to_length_with_env(descriptor.value, env)?);
754754
}
755755
elements.set_length_writable(descriptor.writable);
756+
} else if !descriptor.accessor
757+
&& descriptor.enumerable
758+
&& descriptor.writable
759+
&& descriptor.configurable
760+
&& let Some(index) = array_index_key(&key)
761+
&& elements.dense_data_property_eligible(index)
762+
{
763+
elements.set(index, descriptor.value);
756764
} else {
757765
elements.define_property(key, descriptor);
758766
}
@@ -901,3 +909,32 @@ fn ensure_define_property_target(target: &Value) -> Result<(), RuntimeError> {
901909
}),
902910
}
903911
}
912+
913+
#[cfg(test)]
914+
mod tests {
915+
use std::collections::HashMap;
916+
917+
use super::define_property_on_value_key;
918+
use crate::{ArrayRef, CallEnv, Property, PropertyKey, Value, function::new_realm};
919+
920+
#[test]
921+
fn default_array_index_definitions_use_dense_storage() {
922+
let array = ArrayRef::new_with_length(2);
923+
let mut env = CallEnv::new(new_realm(HashMap::new()));
924+
925+
for (index, value) in [3.0, 5.0].into_iter().enumerate() {
926+
assert_eq!(
927+
define_property_on_value_key(
928+
Value::Array(array.clone()),
929+
PropertyKey::String(index.to_string()),
930+
Property::data(Value::Number(value), true, true, true),
931+
&mut env,
932+
),
933+
Ok(true)
934+
);
935+
}
936+
937+
assert_eq!(array.direct_dense_index_value(0), Some(Value::Number(3.0)));
938+
assert_eq!(array.direct_dense_index_value(1), Some(Value::Number(5.0)));
939+
}
940+
}

tasks/T018-broad-performance.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,69 @@ is `c60e47562d42e47cc83c8c6e60bd07aa71be1406e7b603ebbc36c7236c582342`.
24042404
This unit generalizes across independent external string programs while
24052405
keeping the broad regression guard neutral; B4 and B5 remain active.
24062406

2407+
The exact-SHA hosted workflows for
2408+
`8265d8f11ef79da254dfbc387d4ac84ae60378c4` all completed successfully. CI
2409+
passed the comparison, Test262 subset, and full check jobs; exact Test262
2410+
coverage remained 42,671 pass, one fail, zero timeout, and one actionable gap.
2411+
The hosted broad preview retained 25/25 cases, 225/225 eligible measurements,
2412+
and 600 passing linearity samples. Candidate/base was 0.994670x overall and
2413+
candidate/QuickJS-NG was 0.359130x. The hosted external preview still failed
2414+
B5 at 12.088980x QuickJS-NG for 4/5 JetStream cases, 7.218816x for 6/14
2415+
Kraken cases, and 11.047923x for 23/26 SunSpider cases. Hosted broad raw/report
2416+
SHA-256 are
2417+
`c68bbd588a10436ea952fa32c10af134e2096a44b55355c9e43341a93cebf4e5`
2418+
and `df4f0f419573dc1c98b19ce4cd8a513c8cb510e56f85941dfdee855573f76182`;
2419+
hosted external raw/report SHA-256 are
2420+
`9df5b54ed3f75e3f19d723fbbb8f6f58255922e4065b67bab605e5a114f679d6`
2421+
and `774f2bc9f4a126d77f9649530a7d2c9d7e72fbb904060cf1015d4625018c1448`.
2422+
2423+
The forty-fourth v2 unit follows a fresh external profile into standard array
2424+
creation rather than adding a workload-specific fast path. `CreateDataProperty`
2425+
with the ordinary writable, enumerable, configurable index descriptor used to
2426+
send arrays through generic descriptor storage. Standard operations such as
2427+
`slice`, `map`, and `filter` therefore produced arrays whose indices lived in
2428+
the cold descriptor map, forcing later ordinary indexed writes through generic
2429+
property and environment paths. Compatible default index definitions now stay
2430+
in dense storage when the array is mutable, extensible, length-writable, and
2431+
within the dense index limit. Accessors, special descriptors, frozen, sealed,
2432+
non-extensible, length-locked, sparse-large-index, and descriptor-preserving
2433+
overwrites retain the generic path. A lowest-layer test verifies the dense
2434+
representation. No workload name, source path, iteration count, checksum, or
2435+
expected benchmark value appears in the implementation.
2436+
2437+
Against base binary SHA-256
2438+
`2a7d910a70158e6c92f22674447bbbe56d515b6e4918d11ecce47b22cb609364`,
2439+
candidate binary SHA-256
2440+
`aebef9ebc2a8805c530888ca412c9a21febf94e55350874ce1fefab1918f7680`
2441+
improved independent external programs across three suites. JetStream
2442+
`stanford-crypto-aes` measured 0.826802x base; Kraken
2443+
`stanford-crypto-sha256-iterative`, `stanford-crypto-ccm`, and
2444+
`stanford-crypto-aes` measured 0.295653x, 0.770199x, and 0.827258x. SunSpider
2445+
`crypto-sha1` independently measured 0.843897x. Complete one-block candidate
2446+
and same-window base external previews retained 5/5 JetStream and 23/26
2447+
SunSpider cases; Kraken improved from 10/14 to 11/14 because
2448+
`stanford-crypto-pbkdf2` crossed from timeout to complete. Common-case
2449+
candidate/base suite geometric means were 0.971058x, 0.847388x, and 0.993435x.
2450+
Candidate/QuickJS-NG remained far from B5 at 9.062235x, 4.683388x, and
2451+
6.256767x. Candidate external raw/report SHA-256 are
2452+
`7aab0cb908bfe40cc4d9557f1d839bbad2b66d2cbf52e3a5f788f9126b09e37b`
2453+
and `89a747190833cac84029c61857c2f36895f93c04ef19ba73b1df4c09907bbb49`;
2454+
base raw/report SHA-256 are
2455+
`6f4ec873aa1e39faf81e2245285b42e15316d01390fdf88d7c3c7085f43e4c1d`
2456+
and `e26f74e2b68faf43c38785dc5baa7da7d460d8bd024bea3cb581d0eadb3a2cba`.
2457+
2458+
The complete three-role broad development diagnostic produced all 1,625
2459+
records, 225/225 eligible exact-checksum measurements, zero non-OK samples,
2460+
and 600 linearity samples with all 75 engine/case pairs passing. Candidate/base
2461+
was 0.998272x overall; family ratios ranged from 0.996083x for binding through
2462+
1.000429x for allocation, and the worst case was 1.006811x. Candidate/QuickJS-NG
2463+
was 0.194477x overall, but allocation still failed B4 at 1.137729x. The strict
2464+
analyzer correctly rejected the receipt-less dirty development binaries, so
2465+
this is regression evidence rather than a fixed-hardware claim. Broad raw
2466+
SHA-256: `e71b97feb3314937dccf318007df67a4adc38bad11ad24b5f43548015d9f62b7`.
2467+
This unit materially improves multiple independent external sources while
2468+
keeping the internal regression guard neutral; B4 and B5 remain active.
2469+
24072470
## Historical Broad V1 Baseline
24082471

24092472
The first complete baseline was recorded on 2026-07-15 at commit

0 commit comments

Comments
 (0)