3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types=1); namespace Repro; class CycleValue { public static bool $shutdown = false; private $value; private ?\stdClass $cycleRef; public function __construct($value) { $this->value = $value; // make self cyclically referenced to require GC run to be released $this->cycleRef = new \stdClass(); $this->cycleRef->x = $this; } public function __destruct() { if (!CycleValue::$shutdown) { // recreate self - prevent value to be effectively released until self::$shutdown is set new self($this->value); } } } $refs = []; for ($i = 1; $i <= 3_200; $i++) { $v = new \stdClass(); $v->i = $i; $refs[] = [ \WeakReference::create(new CycleValue($v)), \WeakReference::create($v), ]; if (($i % 100) === 0) { gc_collect_cycles(); if (PHP_VERSION_ID < 80100) { gc_collect_cycles(); } if ($i >= 2_500) { echo count($refs) . ', peak: ' . round(memory_get_peak_usage(true) / (1024 * 1024), 2) . ' MiB, GC runs: ' . (gc_status()['runs'] - $gcRuns) . ', time: ' . round(microtime(true) - $t, 2) . " s \n"; } foreach ($refs as [$rCycle, $rV]) { if ($rCycle->get() !== null) { throw new \Error('CycleValue not released'); } elseif ($rV->get() === null) { throw new \Error('Object released'); } } $t = microtime(true); $gcRuns = gc_status()['runs']; } } CycleValue::$shutdown = true; unset($v); gc_collect_cycles(); if (PHP_VERSION_ID < 80100) { gc_collect_cycles(); } foreach ($refs as [$rCycle, $rV]) { if ($rCycle->get() !== null) { throw new \Error('Shutdown: CycleValue not released'); } elseif ($rV->get() !== null) { throw new \Error('Shutdown: Object not released'); } } echo "done\n";
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 42) Position 1 = 99
Branch analysis from position: 99
2 jumps found. (Code = 44) Position 1 = 101, Position 2 = 3
Branch analysis from position: 101
2 jumps found. (Code = 43) Position 1 = 109, Position 2 = 111
Branch analysis from position: 109
2 jumps found. (Code = 77) Position 1 = 112, Position 2 = 136
Branch analysis from position: 112
2 jumps found. (Code = 78) Position 1 = 113, Position 2 = 136
Branch analysis from position: 113
2 jumps found. (Code = 43) Position 1 = 122, Position 2 = 127
Branch analysis from position: 122
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 127
2 jumps found. (Code = 43) Position 1 = 131, Position 2 = 135
Branch analysis from position: 131
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 135
1 jumps found. (Code = 42) Position 1 = 112
Branch analysis from position: 112
Branch analysis from position: 136
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 136
Branch analysis from position: 111
Branch analysis from position: 3
2 jumps found. (Code = 43) Position 1 = 24, Position 2 = 98
Branch analysis from position: 24
2 jumps found. (Code = 43) Position 1 = 29, Position 2 = 31
Branch analysis from position: 29
2 jumps found. (Code = 43) Position 1 = 33, Position 2 = 64
Branch analysis from position: 33
2 jumps found. (Code = 77) Position 1 = 65, Position 2 = 89
Branch analysis from position: 65
2 jumps found. (Code = 78) Position 1 = 66, Position 2 = 89
Branch analysis from position: 66
2 jumps found. (Code = 43) Position 1 = 75, Position 2 = 80
Branch analysis from position: 75
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 80
2 jumps found. (Code = 43) Position 1 = 84, Position 2 = 88
Branch analysis from position: 84
1 jumps found. (Code = 108) Position 1 = -2
Branch analysis from position: 88
1 jumps found. (Code = 42) Position 1 = 65
Branch analysis from position: 65
Branch analysis from position: 89
2 jumps found. (Code = 44) Position 1 = 101, Position 2 = 3
Branch analysis from position: 101
Branch analysis from position: 3
Branch analysis from position: 89
Branch analysis from position: 64
Branch analysis from position: 31
Branch analysis from position: 98
filename:       /in/L7Dok
function name:  (null)
number of ops:  139
compiled vars:  !0 = $refs, !1 = $i, !2 = $v, !3 = $gcRuns, !4 = $t, !5 = $rCycle, !6 = $rV
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   30     0  E >   ASSIGN                                                   !0, <array>
   31     1        ASSIGN                                                   !1, 1
          2      > JMP                                                      ->99
   32     3    >   NEW                                              $9      'stdClass'
          4        DO_FCALL                                      0          
          5        ASSIGN                                                   !2, $9
   33     6        ASSIGN_OBJ                                               !2, 'i'
          7        OP_DATA                                                  !1
   36     8        INIT_STATIC_METHOD_CALL                                  'WeakReference', 'create'
          9        NEW                                              $14     'Repro%5CCycleValue'
         10        SEND_VAR_EX                                              !2
         11        DO_FCALL                                      0          
         12        SEND_VAR                                                 $14
         13        DO_FCALL                                      0  $16     
         14        INIT_ARRAY                                       ~17     $16
   37    15        INIT_STATIC_METHOD_CALL                                  'WeakReference', 'create'
         16        SEND_VAR                                                 !2
         17        DO_FCALL                                      0  $18     
         18        ADD_ARRAY_ELEMENT                                ~17     $18
   35    19        ASSIGN_DIM                                               !0
   37    20        OP_DATA                                                  ~17
   40    21        MOD                                              ~19     !1, 100
         22        IS_IDENTICAL                                             ~19, 0
         23      > JMPZ                                                     ~20, ->98
   41    24    >   INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_collect_cycles'
         25        DO_FCALL                                      0          
   42    26        FETCH_CONSTANT                                   ~22     'Repro%5CPHP_VERSION_ID'
         27        IS_SMALLER                                               ~22, 80100
         28      > JMPZ                                                     ~23, ->31
         29    >   INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_collect_cycles'
         30        DO_FCALL                                      0          
   44    31    >   IS_SMALLER_OR_EQUAL                                      2500, !1
         32      > JMPZ                                                     ~25, ->64
   45    33    >   INIT_NS_FCALL_BY_NAME                                    'Repro%5Ccount'
         34        SEND_VAR_EX                                              !0
         35        DO_FCALL                                      0  $26     
         36        CONCAT                                           ~27     $26, '%2C+peak%3A+'
         37        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cround'
         38        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cmemory_get_peak_usage'
         39        SEND_VAL_EX                                              <true>
         40        DO_FCALL                                      0  $28     
         41        DIV                                              ~29     $28, 1048576
         42        SEND_VAL_EX                                              ~29
         43        SEND_VAL_EX                                              2
         44        DO_FCALL                                      0  $30     
         45        CONCAT                                           ~31     ~27, $30
         46        CONCAT                                           ~32     ~31, '+MiB%2C+GC+runs%3A+'
         47        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_status'
         48        DO_FCALL                                      0  $33     
         49        FETCH_DIM_R                                      ~34     $33, 'runs'
         50        SUB                                              ~35     ~34, !3
         51        CONCAT                                           ~36     ~32, ~35
         52        CONCAT                                           ~37     ~36, '%2C+time%3A+'
         53        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cround'
         54        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cmicrotime'
         55        SEND_VAL_EX                                              <true>
         56        DO_FCALL                                      0  $38     
         57        SUB                                              ~39     $38, !4
         58        SEND_VAL_EX                                              ~39
         59        SEND_VAL_EX                                              2
         60        DO_FCALL                                      0  $40     
         61        CONCAT                                           ~41     ~37, $40
         62        CONCAT                                           ~42     ~41, '+s+%0A'
         63        ECHO                                                     ~42
   48    64    > > FE_RESET_R                                       $43     !0, ->89
         65    > > FE_FETCH_R                                               $43, $44, ->89
         66    >   FETCH_LIST_R                                     $45     $44, 0
         67        ASSIGN                                                   !5, $45
         68        FETCH_LIST_R                                     $47     $44, 1
         69        ASSIGN                                                   !6, $47
         70        FREE                                                     $44
   49    71        INIT_METHOD_CALL                                         !5, 'get'
         72        DO_FCALL                                      0  $49     
         73        TYPE_CHECK                                  1020          $49
         74      > JMPZ                                                     ~50, ->80
   50    75    >   NEW                                              $51     'Error'
         76        SEND_VAL_EX                                              'CycleValue+not+released'
         77        DO_FCALL                                      0          
         78      > THROW                                         0          $51
   49    79*       JMP                                                      ->88
   51    80    >   INIT_METHOD_CALL                                         !6, 'get'
         81        DO_FCALL                                      0  $53     
         82        TYPE_CHECK                                    2          $53
         83      > JMPZ                                                     ~54, ->88
   52    84    >   NEW                                              $55     'Error'
         85        SEND_VAL_EX                                              'Object+released'
         86        DO_FCALL                                      0          
         87      > THROW                                         0          $55
   48    88    > > JMP                                                      ->65
         89    >   FE_FREE                                                  $43
   56    90        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cmicrotime'
         91        SEND_VAL_EX                                              <true>
         92        DO_FCALL                                      0  $57     
         93        ASSIGN                                                   !4, $57
   57    94        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_status'
         95        DO_FCALL                                      0  $59     
         96        FETCH_DIM_R                                      ~60     $59, 'runs'
         97        ASSIGN                                                   !3, ~60
   31    98    >   PRE_INC                                                  !1
         99    >   IS_SMALLER_OR_EQUAL                                      !1, 3200
        100      > JMPNZ                                                    ~63, ->3
   61   101    >   ASSIGN_STATIC_PROP                                       'shutdown', 'Repro%5CCycleValue'
        102        OP_DATA                                                  <true>
   62   103        UNSET_CV                                                 !2
   63   104        INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_collect_cycles'
        105        DO_FCALL                                      0          
   64   106        FETCH_CONSTANT                                   ~66     'Repro%5CPHP_VERSION_ID'
        107        IS_SMALLER                                               ~66, 80100
        108      > JMPZ                                                     ~67, ->111
        109    >   INIT_NS_FCALL_BY_NAME                                    'Repro%5Cgc_collect_cycles'
        110        DO_FCALL                                      0          
   66   111    > > FE_RESET_R                                       $69     !0, ->136
        112    > > FE_FETCH_R                                               $69, $70, ->136
        113    >   FETCH_LIST_R                                     $71     $70, 0
        114        ASSIGN                                                   !5, $71
        115        FETCH_LIST_R                                     $73     $70, 1
        116        ASSIGN                                                   !6, $73
        117        FREE                                                     $70
   67   118        INIT_METHOD_CALL                                         !5, 'get'
        119        DO_FCALL                                      0  $75     
        120        TYPE_CHECK                                  1020          $75
        121      > JMPZ                                                     ~76, ->127
   68   122    >   NEW                                              $77     'Error'
        123        SEND_VAL_EX                                              'Shutdown%3A+CycleValue+not+released'
        124        DO_FCALL                                      0          
        125      > THROW                                         0          $77
   67   126*       JMP                                                      ->135
   69   127    >   INIT_METHOD_CALL                                         !6, 'get'
        128        DO_FCALL                                      0  $79     
        129        TYPE_CHECK                                  1020          $79
        130      > JMPZ                                                     ~80, ->135
   70   131    >   NEW                                              $81     'Error'
        132        SEND_VAL_EX                                              'Shutdown%3A+Object+not+released'
        133        DO_FCALL                                      0          
        134      > THROW                                         0          $81
   66   135    > > JMP                                                      ->112
        136    >   FE_FREE                                                  $69
   74   137        ECHO                                                     'done%0A'
        138      > RETURN                                                   1

Class Repro\CycleValue:
Function __construct:
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/L7Dok
function name:  __construct
number of ops:  12
compiled vars:  !0 = $value
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   14     0  E >   RECV                                             !0      
   15     1        ASSIGN_OBJ                                               'value'
          2        OP_DATA                                                  !0
   18     3        NEW                                              $3      'stdClass'
          4        DO_FCALL                                      0          
          5        ASSIGN_OBJ                                               'cycleRef'
          6        OP_DATA                                                  $3
   19     7        FETCH_THIS                                       ~7      
          8        FETCH_OBJ_W                                      $5      'cycleRef'
          9        ASSIGN_OBJ                                               $5, 'x'
         10        OP_DATA                                                  ~7
   20    11      > RETURN                                                   null

End of function __construct

Function __destruct:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 3, Position 2 = 9
Branch analysis from position: 3
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 9
filename:       /in/L7Dok
function name:  __destruct
number of ops:  10
compiled vars:  none
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   23     0  E >   FETCH_STATIC_PROP_R          unknown             ~0      'shutdown'
          1        BOOL_NOT                                         ~1      ~0
          2      > JMPZ                                                     ~1, ->9
   25     3    >   NEW                          self                $2      
          4        CHECK_FUNC_ARG                                           
          5        FETCH_OBJ_FUNC_ARG                               $3      'value'
          6        SEND_FUNC_ARG                                            $3
          7        DO_FCALL                                      0          
          8        FREE                                                     $2
   27     9    > > RETURN                                                   null

End of function __destruct

End of class Repro\CycleValue.

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
148.16 ms | 1110 KiB | 19 Q