[PHP-CVS] [php-src] master: Merge branch 'PHP-8.4' into PHP-8.5
[email protected] (Ilia Alshanetsky)
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-24T09:39:23-04:00
Commit: https://github.com/php/php-src/commit/d0be324a6daa4bd72da0f78933c8d28ce32eaef6
Raw diff: https://github.com/php/php-src/commit/d0be324a6daa4bd72da0f78933c8d28ce32eaef6.diff
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
JIT: persist the SHM op_array in trace exit_info
Changed paths:
A ext/opcache/tests/jit/gh21710.inc
A ext/opcache/tests/jit/gh21710.phpt
M NEWS
M ext/opcache/jit/zend_jit_trace.c
Diff:
diff --git a/NEWS b/NEWS
index 283c90bad870..bb7c34323cea 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,9 @@ PHP NEWS
- Opcache:
. Fixed opcache.protect_memory race under ZTS. (realFlowControl)
+ . Fixed a tracing JIT crash when compiling a side trace for a method of a
+ class that could not be stored in the inheritance cache. (GH-21710)
+ (Arnaud, iliaal)
- PDO:
. Fixed a leak when a persistent connection failed a liveness check
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index 7e1ab5d16012..655c84e3f496 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -147,6 +147,11 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t
}
if (JIT_G(current_frame)) {
op_array = &JIT_G(current_frame)->func->op_array;
+ if (!(op_array->fn_flags & ZEND_ACC_IMMUTABLE)) {
+ zend_jit_op_array_trace_extension *jit_extension =
+ (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
+ op_array = jit_extension->op_array;
+ }
stack_size = op_array->last_var + op_array->T;
if (stack_size) {
stack = JIT_G(current_frame)->stack;
diff --git a/ext/opcache/tests/jit/gh21710.inc b/ext/opcache/tests/jit/gh21710.inc
new file mode 100644
index 000000000000..a727c8f12560
--- /dev/null
+++ b/ext/opcache/tests/jit/gh21710.inc
@@ -0,0 +1,15 @@
+<?php
+if (getenv('call_user_func')) {
+ eval('class P {}');
+}
+
+class C extends P {
+ static function f($v) {
+ return $v[0];
+ if ($a) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+}
diff --git a/ext/opcache/tests/jit/gh21710.phpt b/ext/opcache/tests/jit/gh21710.phpt
new file mode 100644
index 000000000000..d175ab4c7014
--- /dev/null
+++ b/ext/opcache/tests/jit/gh21710.phpt
@@ -0,0 +1,50 @@
+--TEST--
+GH-21710: tracing JIT side-trace compile with a heap-copied linked method
+--EXTENSIONS--
+opcache
+pcntl
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=0
+opcache.jit=tracing
+opcache.jit_buffer_size=64M
+--ENV--
+call_user_func=call_user_func
+--SKIPIF--
+<?php
+if (!function_exists('pcntl_fork')) die('skip pcntl_fork() not available');
+if (!(opcache_get_status()['jit']['on'] ?? false)) die('skip JIT is not available');
+?>
+--FILE--
+<?php
+$pid = pcntl_fork();
+if ($pid === 0) {
+ require __DIR__ . '/gh21710.inc';
+ for ($i = 0; $i < 1000; $i++) {
+ getenv('call_user_func')('C::f', [false]);
+ }
+ exit(0);
+}
+if ($pid === -1) {
+ echo "pcntl_fork() failed\n";
+ exit(1);
+}
+
+pcntl_waitpid($pid, $status, 0);
+
+$buf = [];
+for ($i = 0; $i < 100; $i++) {
+ $buf[] = str_repeat('a', $i * 100);
+}
+
+require __DIR__ . '/gh21710.inc';
+
+for ($i = 0; $i < 1000; $i++) {
+ getenv('call_user_func')('C::f', [true]);
+}
+
+var_dump(getenv('call_user_func')('C::f', [true]));
+?>
+--EXPECT--
+bool(true)