Skip to content

Commit d0be324

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: JIT: persist the SHM op_array in trace exit_info
2 parents 0990de7 + 7873640 commit d0be324

4 files changed

Lines changed: 73 additions & 0 deletions

File tree

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ PHP NEWS
3333

3434
- Opcache:
3535
. Fixed opcache.protect_memory race under ZTS. (realFlowControl)
36+
. Fixed a tracing JIT crash when compiling a side trace for a method of a
37+
class that could not be stored in the inheritance cache. (GH-21710)
38+
(Arnaud, iliaal)
3639

3740
- PDO:
3841
. Fixed a leak when a persistent connection failed a liveness check

ext/opcache/jit/zend_jit_trace.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ static uint32_t zend_jit_trace_get_exit_point(const zend_op *to_opline, uint32_t
147147
}
148148
if (JIT_G(current_frame)) {
149149
op_array = &JIT_G(current_frame)->func->op_array;
150+
if (!(op_array->fn_flags & ZEND_ACC_IMMUTABLE)) {
151+
zend_jit_op_array_trace_extension *jit_extension =
152+
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
153+
op_array = jit_extension->op_array;
154+
}
150155
stack_size = op_array->last_var + op_array->T;
151156
if (stack_size) {
152157
stack = JIT_G(current_frame)->stack;

ext/opcache/tests/jit/gh21710.inc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
if (getenv('call_user_func')) {
3+
eval('class P {}');
4+
}
5+
6+
class C extends P {
7+
static function f($v) {
8+
return $v[0];
9+
if ($a) {
10+
return 1;
11+
} else {
12+
return 2;
13+
}
14+
}
15+
}

ext/opcache/tests/jit/gh21710.phpt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--TEST--
2+
GH-21710: tracing JIT side-trace compile with a heap-copied linked method
3+
--EXTENSIONS--
4+
opcache
5+
pcntl
6+
--INI--
7+
opcache.enable=1
8+
opcache.enable_cli=1
9+
opcache.file_update_protection=0
10+
opcache.jit=tracing
11+
opcache.jit_buffer_size=64M
12+
--ENV--
13+
call_user_func=call_user_func
14+
--SKIPIF--
15+
<?php
16+
if (!function_exists('pcntl_fork')) die('skip pcntl_fork() not available');
17+
if (!(opcache_get_status()['jit']['on'] ?? false)) die('skip JIT is not available');
18+
?>
19+
--FILE--
20+
<?php
21+
$pid = pcntl_fork();
22+
if ($pid === 0) {
23+
require __DIR__ . '/gh21710.inc';
24+
for ($i = 0; $i < 1000; $i++) {
25+
getenv('call_user_func')('C::f', [false]);
26+
}
27+
exit(0);
28+
}
29+
if ($pid === -1) {
30+
echo "pcntl_fork() failed\n";
31+
exit(1);
32+
}
33+
34+
pcntl_waitpid($pid, $status, 0);
35+
36+
$buf = [];
37+
for ($i = 0; $i < 100; $i++) {
38+
$buf[] = str_repeat('a', $i * 100);
39+
}
40+
41+
require __DIR__ . '/gh21710.inc';
42+
43+
for ($i = 0; $i < 1000; $i++) {
44+
getenv('call_user_func')('C::f', [true]);
45+
}
46+
47+
var_dump(getenv('call_user_func')('C::f', [true]));
48+
?>
49+
--EXPECT--
50+
bool(true)

0 commit comments

Comments
 (0)