Skip to content

Commit 82cb37b

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix GH-22158: JIT observer dispatch through wrong run_time_cache slot
2 parents de39a14 + 19f595f commit 82cb37b

5 files changed

Lines changed: 45 additions & 1 deletion

File tree

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ PHP NEWS
88
. Fixed bug GH-22206 (missing return in global register detection).
99
(P3p111n0)
1010

11+
- Opcache:
12+
. Fixed bug GH-22158 (Tracing JIT dispatches the observer begin handler
13+
through the wrong run_time_cache slot on megamorphic calls). (ptondereau,
14+
iliaal)
15+
1116
- Reflection:
1217
. Fixed bug GH-22324 (Ignore leading namespace separator in
1318
ReflectionParameter::__construct()). (jorgsowa)

ext/opcache/jit/zend_jit_ir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4687,7 +4687,7 @@ static struct jit_observer_fcall_is_unobserved_data jit_observer_fcall_is_unobse
46874687
ir_ref observer_handler_user = ir_ADD_OFFSET(run_time_cache, zend_observer_fcall_op_array_extension * sizeof(void *));
46884688

46894689
ir_MERGE_WITH(if_internal_func_end);
4690-
*observer_handler = ir_PHI_2(IR_ADDR, observer_handler_internal, observer_handler_user);
4690+
*observer_handler = ir_PHI_2(IR_ADDR, observer_handler_user, observer_handler_internal);
46914691
}
46924692

46934693
// JIT: if (*observer_handler == ZEND_OBSERVER_NONE_OBSERVED) {

ext/opcache/tests/jit/gh22158.phpt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
GH-22158 (Tracing JIT dispatches observer begin handler through the wrong run_time_cache slot on megamorphic calls)
3+
--EXTENSIONS--
4+
opcache
5+
zend_test
6+
--INI--
7+
opcache.enable=1
8+
opcache.enable_cli=1
9+
opcache.jit=tracing
10+
opcache.jit_buffer_size=32M
11+
opcache.jit_max_polymorphic_calls=0
12+
zend_test.observer.enabled=1
13+
zend_test.observer.observe_all=1
14+
zend_test.observer.show_output=0
15+
zend_test.observer.reserve_op_array_handle=1
16+
--FILE--
17+
<?php
18+
interface S { public function f(): int; }
19+
final class A implements S { public function f(): int { return 1; } }
20+
final class B implements S { public function f(): int { return 2; } }
21+
final class C implements S { public function f(): int { return 3; } }
22+
final class D implements S { public function f(): int { return 4; } }
23+
final class E implements S { public function f(): int { return 5; } }
24+
25+
$o = [new A, new B, new C, new D, new E];
26+
$t = 0;
27+
for ($i = 0; $i < 200000; $i++) {
28+
$t += $o[$i % 5]->f();
29+
}
30+
echo $t, "\n";
31+
?>
32+
--EXPECT--
33+
600000

ext/zend_test/observer.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "php_test.h"
1919
#include "observer.h"
2020
#include "zend_observer.h"
21+
#include "zend_extensions.h"
2122
#include "zend_smart_str.h"
2223
#include "ext/standard/php_var.h"
2324
#include "zend_generators.h"
@@ -378,6 +379,7 @@ PHP_INI_BEGIN()
378379
STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals)
379380
STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_destroy", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_destroy, zend_zend_test_globals, zend_test_globals)
380381
STD_PHP_INI_BOOLEAN("zend_test.observer.execute_internal", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_execute_internal, zend_zend_test_globals, zend_test_globals)
382+
STD_PHP_INI_BOOLEAN("zend_test.observer.reserve_op_array_handle", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_reserve_op_array_handle, zend_zend_test_globals, zend_test_globals)
381383
PHP_INI_END()
382384

383385
void zend_test_observer_init(INIT_FUNC_ARGS)
@@ -386,6 +388,9 @@ void zend_test_observer_init(INIT_FUNC_ARGS)
386388
if (type != MODULE_TEMPORARY) {
387389
REGISTER_INI_ENTRIES();
388390
if (ZT_G(observer_enabled)) {
391+
if (ZT_G(observer_reserve_op_array_handle)) {
392+
zend_get_op_array_extension_handle("zend_test");
393+
}
389394
zend_observer_fcall_register(observer_fcall_init);
390395
}
391396
} else {

ext/zend_test/php_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
5151
int observer_fiber_switch;
5252
int observer_fiber_destroy;
5353
int observer_execute_internal;
54+
int observer_reserve_op_array_handle;
5455
HashTable *global_weakmap;
5556
int replace_zend_execute_ex;
5657
int register_passes;

0 commit comments

Comments
 (0)