Files
ladybird/Tests/LibJS/Bytecode/expected/switch-scoping.txt
Andreas Kling 51758f3022 LibJS: Make bytecode register allocator O(1)
Generator::allocate_register used to scan the free pool to find the
lowest-numbered register and then Vec::remove it, making every
allocation O(n) in the size of the pool. When loading https://x.com/
on my Linux machine, we spent ~800ms in this function alone!

This logic only existed to match the C++ register allocation ordering
while transitioning from C++ to Rust in the LibJS compiler, so now
we can simply get rid of it and make it instant. :^)

So drop the "always hand out the lowest-numbered free register" policy
and use the pool as a plain LIFO stack. Pushing and popping the back
of the Vec are both O(1), and peak register usage is unchanged since
the policy only affects which specific register gets reused, not how
aggressively.
2026-04-21 13:59:55 +02:00

87 lines
2.4 KiB
Plaintext

$fc23251f switch-scoping.js:15:1
Registers: 11
Blocks: 1
Constants:
[0] = Undefined
[1] = Int32(1)
[2] = Int32(2)
block0:
[ 0] GetGlobal dst:reg6, `console`
[ 18] GetById dst:reg7, base:reg6, `log` (console.log)
[ 38] GetGlobal dst:reg9, `switchWithBlockDecl`
[ 50] Call dst:reg8, callee:reg9, this_value:Undefined, switchWithBlockDecl, arguments:[Int32(1)]
[ 78] Call dst:reg5, callee:reg7, this_value:reg6, console.log, arguments:[reg8]
[ a0] GetGlobal dst:reg6, `console`
[ b8] GetById dst:reg8, base:reg6, `log` (console.log)
[ d8] GetGlobal dst:reg10, `switchWithBlockDecl`
[ f0] Call dst:reg9, callee:reg10, this_value:Undefined, switchWithBlockDecl, arguments:[Int32(2)]
[ 118] Call dst:reg7, callee:reg8, this_value:reg6, console.log, arguments:[reg9]
[ 140] End value:reg7
switchWithBlockDecl$2b5ecfcd switch-scoping.js:2:5
Registers: 7
Blocks: 7
Locals: result~0
Constants:
[0] = Undefined
[1] = Int32(1)
[2] = Int32(2)
[3] = String("one")
[4] = String("two")
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov dst:result~0, src:Undefined
[ 18] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 28] CreateMutableBinding environment:reg5, `a`, can_be_deleted:false
[ 38] CreateMutableBinding environment:reg5, `b`, can_be_deleted:false
block1:
[ 48] JumpStrictlyEquals lhs:Int32(1), rhs:arg0, true_target:block4, false_target:block2
block2:
[ 60] JumpStrictlyEquals lhs:Int32(2), rhs:arg0, true_target:block5, false_target:block3
block3:
[ 78] Jump target:block6
block4:
[ 80] InitializeLexicalBinding `a`, src:String("one")
[ 98] NewFunction dst:reg6, shared_function_data_index:0 (result)
[ b0] Mov dst:result~0, src:reg6
[ c0] Jump target:block6
block5:
[ c8] InitializeLexicalBinding `b`, src:String("two")
[ e0] NewFunction dst:reg6, shared_function_data_index:1 (result)
[ f8] Mov dst:result~0, src:reg6
block6:
[ 108] SetLexicalEnvironment environment:reg4
[ 110] Call dst:reg5, callee:result~0, this_value:Undefined, result
[ 130] Return value:reg5
result$9ed940b6 switch-scoping.js:6:22
Registers: 6
Blocks: 1
block0:
[ 0] GetBinding dst:reg5, `a`
[ 18] Return value:reg5
result$78d6c64d switch-scoping.js:10:22
Registers: 6
Blocks: 1
block0:
[ 0] GetBinding dst:reg5, `b`
[ 18] Return value:reg5
"one"
"two"