Memory consumption regression in 0.12.83

Bug report

It seems that there is a memory consumption regression in version 0.12.83 caused by this. Phpstan throws the following error when analysing the project:

     mmap() failed: [12] Cannot allocate memory                                              
     PHP Fatal error:  Out of memory (allocated 4665122816) (tried to allocate 4294967304    
     bytes) in                                                                               
     phar:///___/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeRes  
     olver.php on line 574

Since that line does $throwPoints = \array_merge($throwPoints, $branchScopeStatementResult->getThrowPoints()); it leads me to believe that it has something to do with the new exception funcionality. However, I do not understand phpstan internals so maybe I'm wrong. But it is definitely strange that it tries to allocate 4 more gigabytes.

Unfortunately, the project is not open source so I can't just link the source code here. But to give you a rough context it's about 5k PHP files with a total of about 600k LoC. I'm running phpstan with php 7.4 in a vagrant VM with 6 GB of RAM (barely enough to analyse the whole project with 0.12.82). (I also tried running it on host with a larger amount of RAM, but it was still not enough: Allowed memory size of 12884901888 bytes exhausted (tried to allocate 8589934600 bytes)). I'm not sure how much it matters but the project is not very well written with respect to @throws. Most of the methods don't have it and if it's there it's mostly just whatever phpstorm complained about. 😄

Perhaps using [$a, $b] instead of array_merge($a, $b) would be better for memory consumption? OFC it's not as nice of a data structure, but if it were to save gigabytes of memory usage it would seem worth it to me. Here is a small PoC with roughly what I suspect is going on:

<?php

ini_set('memory_limit', '1G');

$o = (object) [];
$node = [$o];
$intermediaryArrays = [];

for ($i = 0; $i < 10; $i++) {
    //$level = array_merge($node, $node, $node, $node, $node); // flat
    $level = [$node, $node, $node, $node]; // tree
    $intermediaryArrays[] = $level;
    $node = $level;
}

echo number_format(memory_get_usage()) . "\n";

With "flat" it outputs: 626,070,984
With "tree" it outputs: 396,320

Expected output

Memory consumption should be roughly in line with 0.12.82 + a reasonable amount for the new functionality.