Skip to content

swoole causes PHP 8.0.1 JIT enable to fail. #3986

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

Closed
Alion548 opened this issue Jan 8, 2021 · 8 comments
Closed

swoole causes PHP 8.0.1 JIT enable to fail. #3986

Alion548 opened this issue Jan 8, 2021 · 8 comments

Comments

@Alion548
Copy link

Alion548 commented Jan 8, 2021

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a simple script for reproducing the error.
PHP Warning:  JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled. in Unknown on line 0

The error disappears when the swoole extension is disabled.

  1. What version of Swoole are you using (show your php --ri swoole)?
php --ri swoole
PHP Warning:  JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled. in Unknown on line 0

swoole

Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 4.6.0
Built => Jan  8 2021 06:02:04
coroutine => enabled
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.1.1i FIPS  8 Dec 2020
dtls => enabled
http2 => enabled
zlib => 1.2.11
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
uname -a
Linux Fedora 33 5.10.5-xanmod1 #1 SMP Thu Jan 7 09:12:41 CST 2021 x86_64 x86_64 x86_64 GNU/Linux

php -v
PHP Warning:  JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled. in Unknown on line 0
PHP 8.0.1 (cli) (built: Jan  8 2021 06:00:24) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.1, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.1, Copyright (c), by Zend Technologies
zend_extension = opcache.so

opcache.enable = 1
opcache.enable_cli = 1
opcache.validate_timestamps = 1
; opcache.save_comments = 1
opcache.revalidate_freq = 15
opcache.max_accelerated_files = 1024
opcache.memory_consumption = 64
opcache.interned_strings_buffer = 8

opcache.jit = 1205
opcache.jit_buffer_size = 64M
GCC Extended Parameters

ENV CC="ccache gcc"
ENV CFLAGS="-fpic -fpie -O3 -march=native -mno-avx"
ENV CXX="ccache g++"
ENV CXXFLAGS="-fpic -fpie -O3 -march=native -mno-avx"
ENV LDFLAGS="-Wl,-O1 -Wl,--hash-style=both -pie"
@dotdevio
Copy link

dotdevio commented Jan 8, 2021

Same issue swoole 4.6.0 & php 8.0.1 (on linux)

@ywp-yywwpp
Copy link

mac 10.15.7 ..... same issue. swoole 4.6.0. php-8.0.1

@Socengel
Copy link

Socengel commented Jan 9, 2021

version with docker
4.5.10 - php 8.0.0 works (phpswoole/swoole:4.5.10-php-8.0-dev) "total-time:0.040979146957397"
4.6.0 - php 8.0.1 not works (phpswoole/swoole:4.6.0-php-8.0-dev) "total-time:0.85911083221436" and same warning

test code

var_dump(opcache_get_status()['jit']);

class Test
{
    public function index()
    {
        for ($y = -39; $y < 39; $y++) {
            printf("\n");

            for ($x = -39; $x < 39; $x++) {
                $i = $this->mandelbrot(
                    $x / 40.0,
                    $y / 40.0
                );

                if ($i == 0) {
                    printf("*");
                } else {
                    printf(" ");
                }
            }
        }

        printf("\n");
    }

    private function mandelbrot($x, $y)
    {
        $cr = $y - 0.5;
        $ci = $x;
        $zi = 0.0;
        $zr = 0.0;
        $i = 0;

        while (1) {
            $i++;

            $temp = $zr * $zi;

            $zr2 = $zr * $zr;
            $zi2 = $zi * $zi;

            $zr = $zr2 - $zi2 + $cr;
            $zi = $temp + $temp + $ci;

            if ($zi2 + $zr2 > 16) {
                return $i;
            }

            if ($i > 5000) {
                return 0;
            }
        }
    }

}


$server = new \Swoole\Http\Server('0.0.0.0', 8000);

$server->on('start', function () {
    $time = microtime(true);
    (new Test())->index();
    var_dump('total-time:' . (microtime(true) - $time));
});

$server->on('request', function () {

});

$server->start();

@Socengel
Copy link

Socengel commented Jan 11, 2021

this is PHP problem in opcache jit. there is check - https://github.com/php/php-src/blob/e497a9f241bbfecf7bef24631b7d7ee666e23363/ext/opcache/jit/zend_jit.c#L4191
swoole uses opcode 57,58 silence operator (@), and 79 EXIT (die(), exit()).
i think EXIT opcode needed to catch exit and throw ExitExeptions this is basic behavior that not easy to change.

Possible solution is to fork php-src 8.0.1 branch, change this loop (continue if opcode is (57,58,79)), and compile from source. Then it works. Use this if you know what are you doing, otherways i recommend use 8.0.1 without jit. I think there is no other ways to run 8.0.1 with jit and swoole right now.

if developers of php adds something like "user opcode override whitelist" where users can define codes that not disable jit. problem will be solved.

for (i = 0; i <= 256; i++) {
    if (zend_get_user_opcode_handler(i) != NULL) {
        if (i == 57|| i == 58 || i == 79) continue;
        zend_error(E_WARNING, "JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled.");
        JIT_G(enabled) = 0;
        JIT_G(on) = 0;
        return FAILURE;
    }
}

@fdreamsu
Copy link

this is PHP problem in opcache jit. there is check - https://github.com/php/php-src/blob/e497a9f241bbfecf7bef24631b7d7ee666e23363/ext/opcache/jit/zend_jit.c#L4191
swoole uses opcode 57,58 silence operator (@), and 79 EXIT (die(), exit()).
i think EXIT opcode needed to catch exit and throw ExitCodeExeptions it's basic behavior that not easy to change.

Possible solution is to fork php-src 8.0.1 branch change this loop (continue if opcode is (57,58,79)), and compile from source. then it works. use this if you know what are you doing, otherways i recommend use 8.0.1 without jit. I think there is no other ways to run 8.0.1 with jit and swoole right now.

if developers of php adds something like "user opcode override whitelist" where users can define codes that not disable jit. problem will be solved.

for (i = 0; i <= 256; i++) {
    if (zend_get_user_opcode_handler(i) != NULL) {
        if (i == 57|| i == 58 || i == 79) continue;
        zend_error(E_WARNING, "JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled.");
        JIT_G(enabled) = 0;
        JIT_G(on) = 0;
        return FAILURE;
    }
}

Work like a charm.

@dotdevio
Copy link

I created small issue https://bugs.php.net/bug.php?id=80621 and hope php dev team can help us fix this issue.

@Socengel
Copy link

There also a way to not override opcodes. Reactphp for example lives in pure php process and works fine it's just responsibility of developer and testing quality. At all engeneer can accidentially turn off your server, application must be ready for this. Maybe if swoole add something like safe mode whitch is turned on by default, but when manually disabled swoole not catch exit and silence at all. This can add more flexibility.

@twose
Copy link
Member

twose commented Jan 27, 2021

#4029 can temporarily solve this problem

@matyhtf matyhtf closed this as completed Jan 28, 2021
@matyhtf matyhtf added the fixed label Jan 28, 2021
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

7 participants