Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ PHP NEWS
. Fixed curl_reset() retaining CURLOPT_PRIVATE after reset. (lacatoire)

- Opcache:
. Fixed bug GH-25220 (JIT hot counters segfault when shared memory is
exhausted during script JIT setup). (rafamolina1)
. Fixed bug GH-25165 (Tracing JIT loops forever once opcache.jit_buffer_size
is exhausted while compiling side traces). (Ilia Alshanetsky)
. Fixed bug GH-25164 (Function JIT loop calling a user function runs once
Expand Down
6 changes: 6 additions & 0 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3388,6 +3388,12 @@ int zend_jit_script(zend_script *script)
for (i = 0; i < call_graph.op_arrays_count; i++) {
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
}
} else {
/* Remaining op_arrays still point at func_info in the arena
released below. Already-setup ones keep their SHM jit_extension. */
for (; i < call_graph.op_arrays_count; i++) {
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
}
}
zend_arena_release(&CG(arena), checkpoint);
return FAILURE;
Expand Down
68 changes: 68 additions & 0 deletions ext/opcache/tests/jit/gh25220.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
--TEST--
GH-25220 (JIT hot counters segfault when shared memory is exhausted during script JIT setup)
--EXTENSIONS--
opcache
--SKIPIF--
<?php
if (PHP_OS_FAMILY === 'Windows') die('skip Windows SHM accounting differs');
?>
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit=1235
opcache.jit_buffer_size=64M
opcache.jit_hot_func=1
opcache.memory_consumption=8
opcache.max_accelerated_files=10000
opcache.interned_strings_buffer=1
opcache.file_update_protection=0
opcache.validate_timestamps=0
opcache.jit_max_root_traces=1024
opcache.jit_max_side_traces=128
opcache.jit_max_exit_counters=8192
memory_limit=-1
--FILE--
<?php
$dir = sys_get_temp_dir() . '/gh25220';
@mkdir($dir, 0777, true);

$n = 150;
$methods = 50;

for ($i = 0; $i < $n; $i++) {
$calls = '';
$m = '';
for ($k = 1; $k < $methods; $k++) {
$calls .= " \$a += \$this->m$k(\$x + $k);\n";
$m .= " public function m$k(int \$x): int { \$t = \$x + $k; return \$t > 3 ? \$t : \$t + $k; }\n";
}
file_put_contents("$dir/C$i.php",
"<?php\nfinal class C$i {\n public function m0(int \$x): int {\n \$a = 0;\n$calls return \$a;\n }\n$m}\n"
);
}

$sum = 0;
for ($pass = 0; $pass < 2; $pass++) {
for ($i = 0; $i < $n; $i++) {
if ($pass === 0) {
require "$dir/C$i.php";
}
$class = "C$i";
$o = new $class();
$sum += $o->m0(1);
$sum += $o->m0(2);
}
}

echo "ok\n";
?>
--CLEAN--
<?php
$dir = sys_get_temp_dir() . '/gh25220';
foreach (glob($dir . '/*.php') ?: [] as $f) {
@unlink($f);
}
@rmdir($dir);
?>
--EXPECT--
ok
Loading