Swoole-src: swoole causes PHP 8.0.1 JIT enable to fail.

Created on 8 Jan 2021  ·  8Comments  ·  Source: swoole/swoole-src

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

```ini
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

```text
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"
PHP8 fixed

Most helpful comment

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;
    }
}

All 8 comments

Same issue swoole 4.6.0 & php 8.0.1 (on linux)

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

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();

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;
    }
}

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.

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

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.

4029 can temporarily solve this problem

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lotarbo picture lotarbo  ·  4Comments

kings36503 picture kings36503  ·  3Comments

AndyChanCode picture AndyChanCode  ·  3Comments

godtail picture godtail  ·  4Comments

jobs-git picture jobs-git  ·  3Comments