From f164e18a559fd2d055460cf334ddabb2d0d33d53 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 8 May 2024 13:08:38 +0200 Subject: [PATCH] LibJS/Bytecode: Bunch all tests together in switch statement codegen Before this change, switch codegen would interleave bytecode like this: (test for case 1) (code for case 1) (test for case 2) (code for case 2) This meant that we often had to make many large jumps while looking for the matching case, since code for each case can be huge. It now looks like this instead: (test for case 1) (test for case 2) (code for case 1) (code for case 2) This way, we can just fall through the tests until we hit one that fits, without having to make any large jumps. --- Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 038cf0e5c7..a6f70b0c53 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -2586,6 +2587,12 @@ Bytecode::CodeGenerationErrorOr> SwitchStatement::genera generator.emit(Bytecode::Label { *next_test_block }); + Queue test_blocks; + for (auto& switch_case : m_cases) { + if (switch_case->test()) + test_blocks.enqueue(&generator.make_block()); + } + for (auto& switch_case : m_cases) { auto& case_block = generator.make_block(); if (switch_case->test()) { @@ -2593,7 +2600,7 @@ Bytecode::CodeGenerationErrorOr> SwitchStatement::genera auto test_value = TRY(switch_case->test()->generate_bytecode(generator)).value(); auto result = generator.allocate_register(); generator.emit(result, test_value, discriminant); - next_test_block = &generator.make_block(); + next_test_block = test_blocks.dequeue(); generator.emit( result, Bytecode::Label { case_block },