Skip to content

8.4.11: JIT issue with Generator #19493

@AlexAT

Description

@AlexAT

Description

php.ini

zend_extension=opcache.so
opcache.enable_cli=on
opcache.jit=tracing
opcache.jit_buffer_size=32M

Reproducer code:

<?php

function test()
{
  $iterations = 1000000;
  $counter = 0;

  yield true;
  while (true) {
    $counter++;
    if ($counter == $iterations) break;
if (mt_rand(0, 10000000) > 9999999) { echo("$counter\n"); return; } # take note iteration count is lower!
    yield true;
  }
  echo($counter."\n");
}

foreach (test() as $v) { }

Bug description:
Results in loop mostly (but not always!) terminating by injected mt_rand() based termination condition at fixed counter value of "65".

It seems counter variable somehow stops increasing at generator invocations. In Windows build it does stop at "65" as well.

If mt_rand() termination is commented out, script expectedly never completes at wrong ("65") runs, so most of the time, while it should always complete at 1000000 iterations. I do not know why it completes sometimes, maybe due to address space randomization, maybe due to something else.

Disabling JIT resolves the issue, the script always works correctly.

Confirmed in both 8.4.10 for Linux x86-64 NTS built from source and 8.4.11 NTS Windows ZIP build downloaded from PHP site.

Correct output for multiple consecutive runs (random values and "1000000" completions as expected):

963792
956411
1000000
209645
1000000
75357
1000000
842156
512774
1000000

...

Problem occurence output (take note how much "65" appears there):

822760
65
65
1000000
65
65
65
65
1000000
65

...

Code workaround found (should help to debug it):

<?php

function test()
{
  $iterations = 1000000;
  $counter = 0;

  yield true;
  while (true) {
    if ($counter == $iterations) break;
    $counter++;
if (mt_rand(0, 10000000) > 9999999) { echo("$counter\n"); return; } # take note iteration count is lower!
    yield true;
  }
  echo($counter."\n");
}

foreach (test() as $v) { }

(basically, swapping if() clause and counter increment)
makes the script always work properly.

Please tell if I can add anything else to that report.

PHP Version

PHP 8.4.10 (cli) (built: Jul 11 2025 10:12:19) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.10, Copyright (c), by Zend Technologies

PHP 8.4.11 (cli) (built: Jul 29 2025 18:02:29) (NTS Visual C++ 2022 x64)
Copyright (c) The PHP Group                                                                                                                                                                             
Zend Engine v4.4.11, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.11, Copyright (c), by Zend Technologies

Operating System

Oracle Linux 10 x86-64, Windows 11 x86-64

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions