Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e8fce29

Browse files
committed
Backport fix GH-17307
This is a backport of GH-17319 to fix GH-17307 on lower branches. Closes GH-17424.
1 parent a2a7287 commit e8fce29

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

‎NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ PHP NEWS
2525
- Intl:
2626
. Fixed bug GH-11874 (intl causing segfault in docker images). (nielsdos)
2727

28+
- Opcache:
29+
. Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos)
30+
2831
- PHPDBG:
2932
. Fix crashes in function registration + test. (nielsdos, Girgias)
3033

‎ext/opcache/jit/zend_jit_arm64.dasc‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8471,6 +8471,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
84718471
{
84728472
uint32_t used_stack;
84738473
bool stack_check = 1;
8474+
const size_t func_type_offset = is_closure ? offsetof(zend_closure, func.type) : offsetof(zend_function, type);
84748475

84758476
// REG0 -> zend_function
84768477
// FCARG1 -> used_stack
@@ -8484,15 +8485,11 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
84848485
used_stack = (ZEND_CALL_FRAME_SLOT + opline->extended_value + ZEND_OBSERVER_ENABLED) * sizeof(zval);
84858486

84868487
| // if (EXPECTED(ZEND_USER_CODE(func->type))) {
8487-
if (!is_closure) {
8488-
| LOAD_32BIT_VAL FCARG1w, used_stack
8489-
| // Check whether REG0 is an internal function.
8490-
| ldrb TMP1w, [REG0, #offsetof(zend_function, type)]
8491-
| TST_32_WITH_CONST TMP1w, 1, TMP2w
8492-
| bne >1
8493-
} else {
8494-
| LOAD_32BIT_VAL FCARG1w, used_stack
8495-
}
8488+
| LOAD_32BIT_VAL FCARG1w, used_stack
8489+
| // Check whether REG0 is an internal function.
8490+
| ldrb TMP1w, [REG0, #func_type_offset]
8491+
| TST_32_WITH_CONST TMP1w, 1, TMP2w
8492+
| bne >1
84968493
| // used_stack += (func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args)) * sizeof(zval);
84978494
| LOAD_32BIT_VAL REG2w, opline->extended_value
84988495
if (!is_closure) {

‎ext/opcache/jit/zend_jit_x86.dasc‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9072,6 +9072,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
90729072
{
90739073
uint32_t used_stack;
90749074
bool stack_check = 1;
9075+
const size_t func_type_offset = is_closure ? offsetof(zend_closure, func.type) : offsetof(zend_function, type);
90759076

90769077
if (func) {
90779078
used_stack = zend_vm_calc_used_stack(opline->extended_value, func);
@@ -9082,13 +9083,9 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
90829083
used_stack = (ZEND_CALL_FRAME_SLOT + opline->extended_value + ZEND_OBSERVER_ENABLED) * sizeof(zval);
90839084

90849085
| // if (EXPECTED(ZEND_USER_CODE(func->type))) {
9085-
if (!is_closure) {
9086-
| test byte [r0 + offsetof(zend_function, type)], 1
9087-
| mov FCARG1a, used_stack
9088-
| jnz >1
9089-
} else {
9090-
| mov FCARG1a, used_stack
9091-
}
9086+
| test byte [r0 + func_type_offset], 1
9087+
| mov FCARG1a, used_stack
9088+
| jnz >1
90929089
| // used_stack += (func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args)) * sizeof(zval);
90939090
| mov edx, opline->extended_value
90949091
if (!is_closure) {

‎ext/opcache/tests/jit/gh17307.phpt‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-17307 (Internal closure causes JIT failure)
3+
--EXTENSIONS--
4+
opcache
5+
simplexml
6+
bcmath
7+
--INI--
8+
opcache.jit=1254
9+
opcache.jit_hot_func=1
10+
opcache.jit_buffer_size=32M
11+
--FILE--
12+
<?php
13+
14+
$simple = new SimpleXMLElement("<root><a/><b/></root>");
15+
16+
function run_loop($firstTerms, $closure) {
17+
foreach ($firstTerms as $firstTerm) {
18+
\debug_zval_dump($firstTerm);
19+
$closure($firstTerm, "10");
20+
}
21+
}
22+
23+
run_loop($simple, bcadd(...));
24+
echo "Done\n";
25+
26+
?>
27+
--EXPECTF--
28+
object(SimpleXMLElement)#%d (0) refcount(3){
29+
}
30+
object(SimpleXMLElement)#%d (0) refcount(3){
31+
}
32+
Done

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /