mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-28 05:52:53 +00:00
LibJS: Stop converting between Object <-> IteratorRecord all the time
This patch makes IteratorRecord an Object. Although it's not exposed to author code, this does allow us to store it in a VM register. Now that we can store it in a VM register, we don't need to convert it back and forth between IteratorRecord and Object when accessing it from bytecode. The big win here is avoiding 3 [[Get]] accesses on every iteration step of for..of loops. There are also a bunch of smaller efficiencies gained. 20% 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:
parent
4966c083df
commit
4699c81fc1
Notes:
sideshowbarker
2024-07-16 22:14:49 +09:00
Author: https://github.com/awesomekling
Commit: 4699c81fc1
Pull-request: https://github.com/SerenityOS/serenity/pull/22194
Reviewed-by: https://github.com/trflynn89
23 changed files with 226 additions and 144 deletions
|
@ -338,7 +338,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
}
|
||||
|
||||
// e. Let iteratorRecord be undefined.
|
||||
Optional<IteratorRecord> iterator_record;
|
||||
GCPtr<IteratorRecord> iterator_record;
|
||||
|
||||
// f. If usingAsyncIterator is not undefined, then
|
||||
if (using_async_iterator) {
|
||||
|
@ -354,7 +354,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
}
|
||||
|
||||
// h. If iteratorRecord is not undefined, then
|
||||
if (iterator_record.has_value()) {
|
||||
if (iterator_record) {
|
||||
GCPtr<Object> array;
|
||||
|
||||
// i. If IsConstructor(C) is true, then
|
||||
|
@ -377,7 +377,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
auto error = vm.throw_completion<TypeError>(ErrorType::ArrayMaxSize);
|
||||
|
||||
// b. Return ? AsyncIteratorClose(iteratorRecord, error).
|
||||
return *TRY(async_iterator_close(vm, iterator_record.value(), move(error)));
|
||||
return *TRY(async_iterator_close(vm, *iterator_record, move(error)));
|
||||
}
|
||||
|
||||
// 2. Let Pk be ! ToString(𝔽(k)).
|
||||
|
@ -433,7 +433,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
|
||||
// b. IfAbruptCloseAsyncIterator(mappedValue, iteratorRecord).
|
||||
if (mapped_value_or_error.is_error()) {
|
||||
TRY(async_iterator_close(vm, iterator_record.value(), mapped_value_or_error));
|
||||
TRY(async_iterator_close(vm, *iterator_record, mapped_value_or_error));
|
||||
return mapped_value_or_error;
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
|
||||
// d. IfAbruptCloseAsyncIterator(mappedValue, iteratorRecord).
|
||||
if (mapped_value_or_error.is_error()) {
|
||||
TRY(async_iterator_close(vm, iterator_record.value(), mapped_value_or_error));
|
||||
TRY(async_iterator_close(vm, *iterator_record, mapped_value_or_error));
|
||||
return mapped_value_or_error;
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from_async)
|
|||
|
||||
// 9. If defineStatus is an abrupt completion, return ? AsyncIteratorClose(iteratorRecord, defineStatus).
|
||||
if (define_status.is_error())
|
||||
return *TRY(iterator_close(vm, iterator_record.value(), define_status.release_error()));
|
||||
return *TRY(iterator_close(vm, *iterator_record, define_status.release_error()));
|
||||
|
||||
// 10. Set k to k + 1.
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue