[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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.