mirror of
https://github.com/RGBCube/serenity
synced 2025-05-15 04:24:59 +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
23 changed files with 226 additions and 144 deletions
|
@ -1225,8 +1225,21 @@ ThrowCompletionOr<void> DeleteByValueWithThis::execute_impl(Bytecode::Interprete
|
|||
ThrowCompletionOr<void> GetIterator::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto iterator = TRY(get_iterator(vm, interpreter.accumulator(), m_hint));
|
||||
interpreter.accumulator() = iterator_to_object(vm, iterator);
|
||||
interpreter.accumulator() = TRY(get_iterator(vm, interpreter.accumulator(), m_hint));
|
||||
return {};
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> GetObjectFromIteratorRecord::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& iterator_record = verify_cast<IteratorRecord>(interpreter.reg(m_iterator_record).as_object());
|
||||
interpreter.reg(m_object) = iterator_record.iterator;
|
||||
return {};
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> GetNextMethodFromIteratorRecord::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& iterator_record = verify_cast<IteratorRecord>(interpreter.reg(m_iterator_record).as_object());
|
||||
interpreter.reg(m_next_method) = iterator_record.next_method;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -1248,8 +1261,7 @@ ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interp
|
|||
ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
|
||||
auto iterator = object_to_iterator(vm, iterator_object);
|
||||
auto& iterator = verify_cast<IteratorRecord>(interpreter.accumulator().as_object());
|
||||
|
||||
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
|
||||
TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} }));
|
||||
|
@ -1259,8 +1271,7 @@ ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& inter
|
|||
ThrowCompletionOr<void> AsyncIteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
|
||||
auto iterator = object_to_iterator(vm, iterator_object);
|
||||
auto& iterator = verify_cast<IteratorRecord>(interpreter.accumulator().as_object());
|
||||
|
||||
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
|
||||
TRY(async_iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value, {} }));
|
||||
|
@ -1270,8 +1281,7 @@ ThrowCompletionOr<void> AsyncIteratorClose::execute_impl(Bytecode::Interpreter&
|
|||
ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto iterator_object = TRY(interpreter.accumulator().to_object(vm));
|
||||
auto iterator = object_to_iterator(vm, iterator_object);
|
||||
auto& iterator = verify_cast<IteratorRecord>(interpreter.accumulator().as_object());
|
||||
|
||||
interpreter.accumulator() = TRY(iterator_next(vm, iterator));
|
||||
return {};
|
||||
|
@ -1818,4 +1828,14 @@ DeprecatedString Catch::to_deprecated_string_impl(Bytecode::Executable const&) c
|
|||
return "Catch"sv;
|
||||
}
|
||||
|
||||
DeprecatedString GetObjectFromIteratorRecord::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||
{
|
||||
return DeprecatedString::formatted("GetObjectFromIteratorRecord object:{} <- iterator_record:{}", m_object, m_iterator_record);
|
||||
}
|
||||
|
||||
DeprecatedString GetNextMethodFromIteratorRecord::to_deprecated_string_impl(Bytecode::Executable const&) const
|
||||
{
|
||||
return DeprecatedString::formatted("GetNextMethodFromIteratorRecord next_method:{} <- iterator_record:{}", m_next_method, m_iterator_record);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue