1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 15:48:12 +00:00

LibJS: Remove dedicated iterator result instructions in favor of GetById

When iterating over an iterable, we get back a JS object with the fields
"value" and "done".

Before this change, we've had two dedicated instructions for retrieving
the two fields: IteratorResultValue and IteratorResultDone. These had no
fast path whatsoever and just did a generic [[Get]] access to fetch the
corresponding property values.

By replacing the instructions with GetById("value") and GetById("done"),
they instantly get caching and JIT fast paths for free, making iterating
over iterables much faster. :^)

26% speed-up on this microbenchmark:

    function go(a) {
        for (const p of a) {
        }
    }
    const a = [];
    a.length = 1_000_000;
    go(a);
This commit is contained in:
Andreas Kling 2023-12-07 16:12:12 +01:00
parent 8d68f94282
commit 350e6c54d7
8 changed files with 26 additions and 96 deletions

View file

@ -3111,20 +3111,6 @@ void Compiler::compile_iterator_next(Bytecode::Op::IteratorNext const&)
check_exception();
}
static Value cxx_iterator_result_done(VM& vm, Value iterator)
{
auto iterator_result = TRY_OR_SET_EXCEPTION(iterator.to_object(vm));
return Value(TRY_OR_SET_EXCEPTION(iterator_complete(vm, iterator_result)));
}
void Compiler::compile_iterator_result_done(Bytecode::Op::IteratorResultDone const&)
{
load_accumulator(ARG1);
native_call((void*)cxx_iterator_result_done);
store_accumulator(RET);
check_exception();
}
static Value cxx_throw_if_not_object(VM& vm, Value value)
{
if (!value.is_object())
@ -3153,20 +3139,6 @@ void Compiler::compile_throw_if_nullish(Bytecode::Op::ThrowIfNullish const&)
check_exception();
}
static Value cxx_iterator_result_value(VM& vm, Value iterator)
{
auto iterator_result = TRY_OR_SET_EXCEPTION(iterator.to_object(vm));
return TRY_OR_SET_EXCEPTION(iterator_value(vm, iterator_result));
}
void Compiler::compile_iterator_result_value(Bytecode::Op::IteratorResultValue const&)
{
load_accumulator(ARG1);
native_call((void*)cxx_iterator_result_value);
store_accumulator(RET);
check_exception();
}
static Value cxx_iterator_close(VM& vm, Value iterator, Completion::Type completion_type, Optional<Value> const& completion_value)
{
auto& iterator_record = verify_cast<IteratorRecord>(iterator.as_object());