LibJS/Bytecode: Do basic compare-and-jump peephole optimization

We now fuse sequences like [LessThan, JumpIf] to JumpLessThan.
This is only allowed for temporaries (i.e VM registers) with no other
references to them.
This commit is contained in:
Andreas Kling 2024-05-09 15:13:31 +02:00 committed by Alexander Kalenik
commit 7654da3851
Notes: sideshowbarker 2024-07-18 00:41:35 +09:00
8 changed files with 166 additions and 28 deletions

View file

@ -362,6 +362,7 @@ FLATTEN_ON_CLANG void Interpreter::run_bytecode(size_t entry_point)
#define SET_UP_LABEL(name) &&handle_##name,
ENUMERATE_BYTECODE_OPS(SET_UP_LABEL)
};
#undef SET_UP_LABEL
#define DISPATCH_NEXT(name) \
do { \
@ -441,6 +442,26 @@ FLATTEN_ON_CLANG void Interpreter::run_bytecode(size_t entry_point)
goto start;
}
#define HANDLE_COMPARISON_OP(op_TitleCase, op_snake_case) \
handle_Jump##op_TitleCase: \
{ \
auto& instruction = *reinterpret_cast<Op::Jump##op_TitleCase const*>(&bytecode[program_counter]); \
auto result = op_snake_case(vm(), get(instruction.lhs()), get(instruction.rhs())); \
if (result.is_error()) { \
if (handle_exception(program_counter, *result.throw_completion().value()) == HandleExceptionResponse::ExitFromExecutable) \
return; \
goto start; \
} \
if (result.value().to_boolean()) \
program_counter = instruction.true_target().address(); \
else \
program_counter = instruction.false_target().address(); \
goto start; \
}
JS_ENUMERATE_COMPARISON_OPS(HANDLE_COMPARISON_OP)
#undef HANDLE_COMPARISON_OP
handle_JumpUndefined: {
auto& instruction = *reinterpret_cast<Op::JumpUndefined const*>(&bytecode[program_counter]);
if (get(instruction.condition()).is_undefined())
@ -2142,6 +2163,18 @@ ByteString JumpNullish::to_byte_string_impl(Bytecode::Executable const& executab
m_false_target);
}
#define HANDLE_COMPARISON_OP(op_TitleCase, op_snake_case) \
ByteString Jump##op_TitleCase::to_byte_string_impl(Bytecode::Executable const& executable) const \
{ \
return ByteString::formatted("Jump" #op_TitleCase " {}, {}, true:{}, false:{}", \
format_operand("lhs"sv, m_lhs, executable), \
format_operand("rhs"sv, m_rhs, executable), \
m_true_target, \
m_false_target); \
}
JS_ENUMERATE_COMPARISON_OPS(HANDLE_COMPARISON_OP)
ByteString JumpUndefined::to_byte_string_impl(Bytecode::Executable const& executable) const
{
return ByteString::formatted("JumpUndefined {}, undefined:{} defined:{}",