Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

primitives seem to be passed via reference instead of by value under some conditions when JIT is enabled on windows #11917

Closed
terrafrost opened this issue Aug 8, 2023 · 7 comments

Comments

@terrafrost
Copy link

terrafrost commented Aug 8, 2023

Description

The following code:

$a = [2147483647,2147483647,2147483647,3,0,0,32,2147483584,127];
echo crc32(json_encode(bitwise_small_split($a))) . "\n";
echo crc32(json_encode(bitwise_small_split($a))) . "\n";
echo crc32(json_encode(bitwise_small_split($a))) . "\n";
echo crc32(json_encode(bitwise_small_split($a))) . "\n";

function bitwise_small_split($val)
{
    $split = 8;
    $vals = [];

    $mask = (1 << $split) - 1;

    $i = $overflow = 0;
    $len = count($val);
    $val[] = 0;
    $remaining = 31;

    while ($i != $len) {
        $digit = $val[$i] & $mask;

        $val[$i] >>= $split;
        if (!$overflow) {
            $remaining -= $split;
            $overflow = $split <= $remaining ? 0 : $split - $remaining;

            if (!$remaining) {
                $i++;
                $remaining = 31;
                $overflow = 0;
            }
        } elseif (++$i != $len) {
            $tempmask = (1 << $overflow) - 1;
            $digit |= ($val[$i] & $tempmask) << $remaining;
            $val[$i] >>= $overflow;
            $remaining = 31 - $overflow;
            $overflow = $split <= $remaining ? 0 : $split - $remaining;
        }

        $vals[] = $digit;
    }

    while ($vals[count($vals) - 1] == 0) {
        unset($vals[count($vals) - 1]);
    }

    return array_reverse($vals);
}

With this php.ini:

zend_extension = C:/php/ext/php_opcache.dll

[opcache]
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=100000
opcache.jit_buffer_size=128M
opcache.jit=tracing

Resulted in this output:

48207660
48207660
1497456976
1497456976

But I expected this output instead:

48207660
48207660
48207660
48207660

I get the expected output when I set opcache.enable to 0 in the php.ini but not when it's set to 1.

Note that sometimes I need to run the PHP file twice before the issue starts appearing. Also, this appears to only be a problem on Windows as I was unable to duplicate the issue with https://github.com/phpseclib/docker-php/tree/8.2jit

PHP Version

PHP 8.2.9

Operating System

Windows 11

@terrafrost terrafrost changed the title primitives seem to be passed via reference instead of by value under some conditions when opcache is enabled primitives seem to be passed via reference instead of by value under some conditions when opcache is enabled on windows Aug 9, 2023
@nielsdos
Copy link
Member

nielsdos commented Aug 9, 2023

What happens if you enable opcache and only disable JIT? I suspect the real issue might be in the JIT instead of opcache.

@terrafrost terrafrost changed the title primitives seem to be passed via reference instead of by value under some conditions when opcache is enabled on windows primitives seem to be passed via reference instead of by value under some conditions when JIT is enabled on windows Aug 9, 2023
@terrafrost
Copy link
Author

terrafrost commented Aug 9, 2023

@nielsdos - good call. The following php.ini does not demonstrate the problem:

[opcache]
opcache.enable=1
opcache.enable_cli=1

I've updated my post accordingly.

@gmutinel
Copy link

Same thing with 8.1.23 on Win11, had to force jit off with

opcache.jit=off

@parallels999
Copy link

Same thing with 8.1.23 on Win11, had to force jit off with

opcache.jit=off

Me too, on Win 10 with 8.2

danog added a commit to danog/php-src that referenced this issue Sep 20, 2023
danog added a commit to danog/php-src that referenced this issue Sep 22, 2023
@dstogov
Copy link
Member

dstogov commented Oct 16, 2023

I can't reproduce the problem on 8.1.26-dev
@nielsdos can you reproduce?

@danog
Copy link
Contributor

danog commented Oct 16, 2023

@dstogov the issue is still present on windows after rebasing on the latest PHP-8.1: https://github.com/php/php-src/actions/runs/6535551162/job/17745266902?pr=12269

@nielsdos
Copy link
Member

@dstogov I can only reproduce it on Windows, not Linux. Reproduces with danog@d788e4f reliably. Bug only occurs when using tracing JIT with optimization level >= 2. Register allocation settings in JIT don't have an influence.

dstogov added a commit to dstogov/php-src that referenced this issue Oct 16, 2023
… of by value under some conditions when JIT is enabled on windows
dstogov added a commit that referenced this issue Oct 16, 2023
* PHP-8.1:
  Fixed GH-11917: primitives seem to be passed via reference instead of by value under some conditions when JIT is enabled on windows (#12451)
dstogov added a commit that referenced this issue Oct 16, 2023
* PHP-8.2:
  Fixed GH-11917: primitives seem to be passed via reference instead of by value under some conditions when JIT is enabled on windows (#12451)
dstogov added a commit that referenced this issue Oct 16, 2023
* PHP-8.3:
  Fixed GH-11917: primitives seem to be passed via reference instead of by value under some conditions when JIT is enabled on windows (#12451)
SakiTakamachi pushed a commit to SakiTakamachi/php-src that referenced this issue Oct 17, 2023
… of by value under some conditions when JIT is enabled on windows (php#12451)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants