LibJS: Avoid IteratorRecord GC-allocation in GetIterator instruction

With this change, `GetIterator` no longer GC-allocates an
`IteratorRecord`. Instead, it stores the iterator record fields in
bytecode registers. This avoids per-iteration allocations in patterns
like: `for (let [x] of array) {}`.

`IteratorRecord` now inherits from `IteratorRecordImpl`, which holds the
iteration state. This allows the existing iteration helpers
(`iterator_next()`, `iterator_step()`, etc.) operate on both the
GC-allocated and the register-backed forms.

Microbenchmarks:
1.1x array-destructuring-assignment-rest.js
1.226x array-destructuring-assignment.js
This commit is contained in:
Aliaksandr Kalenik 2025-10-27 19:46:54 +01:00 committed by Alexander Kalenik
parent a4e3890c05
commit 646457099c
Notes: github-actions[bot] 2025-11-02 19:06:58 +00:00
18 changed files with 252 additions and 235 deletions

View file

@ -25,10 +25,10 @@ StringIterator::StringIterator(String string, Object& prototype)
{
}
BuiltinIterator* StringIterator::as_builtin_iterator_if_next_is_not_redefined(IteratorRecord const& iterator_record)
BuiltinIterator* StringIterator::as_builtin_iterator_if_next_is_not_redefined(Value next_method)
{
if (iterator_record.next_method.is_object()) {
auto const& next_function = iterator_record.next_method.as_object();
if (next_method.is_object()) {
auto const& next_function = next_method.as_object();
if (next_function.is_native_function()) {
auto const& native_function = static_cast<NativeFunction const&>(next_function);
if (native_function.is_string_prototype_next_builtin())