Files
ladybird/Tests/LibJS/Bytecode/expected/block-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

129 lines
3.8 KiB
Plaintext

$975f41e0 block-scoping.js:13:1
Registers: 11
Blocks: 1
Constants:
[0] = Undefined
block0:
[ 0] GetGlobal dst:reg6, `console`
[ 18] GetById dst:reg7, base:reg6, `log` (console.log)
[ 38] GetGlobal dst:reg9, `closureOverBlockScope`
[ 50] Call dst:reg8, callee:reg9, this_value:Undefined, closureOverBlockScope
[ 70] Call dst:reg5, callee:reg7, this_value:reg6, console.log, arguments:[reg8]
[ 98] GetGlobal dst:reg6, `console`
[ b0] GetById dst:reg8, base:reg6, `log` (console.log)
[ d0] GetGlobal dst:reg10, `breakThroughBlockScopes`
[ e8] Call dst:reg9, callee:reg10, this_value:Undefined, breakThroughBlockScopes
[ 108] Call dst:reg7, callee:reg8, this_value:reg6, console.log, arguments:[reg9]
[ 130] End value:reg7
closureOverBlockScope$4f0633f8 block-scoping.js:2:15
Registers: 10
Blocks: 1
Locals: fns~0
Constants:
[0] = Int32(1)
[1] = Int32(2)
[2] = Int32(0)
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] NewArray dst:fns~0
[ 18] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 28] CreateMutableBinding environment:reg5, `x`, can_be_deleted:false
[ 38] InitializeLexicalBinding `x`, src:Int32(1)
[ 50] GetById dst:reg7, base:fns~0, `push` (fns.push)
[ 70] Mov dst:reg8, src:fns~0
[ 80] NewFunction dst:reg9, shared_function_data_index:0
[ 98] Call dst:reg6, callee:reg7, this_value:reg8, fns.push, arguments:[reg9]
[ c0] SetLexicalEnvironment environment:reg4
[ c8] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ d8] CreateMutableBinding environment:reg5, `y`, can_be_deleted:false
[ e8] InitializeLexicalBinding `y`, src:Int32(2)
[ 100] GetById dst:reg7, base:fns~0, `push` (fns.push)
[ 120] Mov dst:reg8, src:fns~0
[ 130] NewFunction dst:reg9, shared_function_data_index:1
[ 148] Call dst:reg6, callee:reg7, this_value:reg8, fns.push, arguments:[reg9]
[ 170] SetLexicalEnvironment environment:reg4
[ 178] GetByValue dst:reg6, base:fns~0, property:Int32(0)
[ 190] Call dst:reg5, callee:reg6, this_value:fns~0, fns[0]
[ 1b0] GetByValue dst:reg7, base:fns~0, property:Int32(1)
[ 1c8] Call dst:reg6, callee:reg7, this_value:fns~0, fns[1]
[ 1e8] Add dst:reg7, lhs:reg5, rhs:reg6
[ 1f8] Return value:reg7
$551734f7 block-scoping.js:5:18
Registers: 6
Blocks: 1
block0:
[ 0] GetBinding dst:reg5, `x`
[ 18] Return value:reg5
$2f14ba8e block-scoping.js:9:18
Registers: 6
Blocks: 1
block0:
[ 0] GetBinding dst:reg5, `y`
[ 18] Return value:reg5
breakThroughBlockScopes$c915ba4a block-scoping.js:16:5
Registers: 8
Blocks: 7
Locals: f~0, i~1, result~2
Constants:
[0] = Undefined
[1] = Int32(0)
[2] = Int32(3)
[3] = Int32(1)
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov2 dst1:result~2, src1:Undefined, dst2:i~1, src2:Int32(0)
[ 20] Jump target:block3
block1:
[ 28] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 38] CreateMutableBinding environment:reg5, `x`, can_be_deleted:false
[ 48] InitializeLexicalBinding `x`, src:i~1
[ 60] NewFunction dst:f~0, shared_function_data_index:0 (f)
[ 78] GetBinding dst:reg6, `x`
[ 90] JumpGreaterThan lhs:reg6, rhs:Int32(1), true_target:block5, false_target:block6
block2:
[ a8] PostfixIncrement dst:reg5, src:i~1
block3:
[ b8] JumpLessThan lhs:i~1, rhs:Int32(3), true_target:block1, false_target:block4
block4:
[ d0] Call dst:reg5, callee:result~2, this_value:Undefined, result
[ f0] Return value:reg5
block5:
[ f8] Mov dst:result~2, src:f~0
[ 108] SetLexicalEnvironment environment:reg4
[ 110] Jump target:block4
block6:
[ 118] SetLexicalEnvironment environment:reg4
[ 120] Jump target:block2
f$551734f7 block-scoping.js:20:21
Registers: 6
Blocks: 1
block0:
[ 0] GetBinding dst:reg5, `x`
[ 18] Return value:reg5
3
2