mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Backport fix GH-17307
This is a backport of GH-17319 to fix GH-17307 on lower branches. Closes GH-17424.
This commit is contained in:
3
NEWS
3
NEWS
@@ -25,6 +25,9 @@ PHP NEWS
|
||||
- Intl:
|
||||
. Fixed bug GH-11874 (intl causing segfault in docker images). (nielsdos)
|
||||
|
||||
- Opcache:
|
||||
. Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos)
|
||||
|
||||
- PHPDBG:
|
||||
. Fix crashes in function registration + test. (nielsdos, Girgias)
|
||||
|
||||
|
||||
@@ -8471,6 +8471,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
|
||||
{
|
||||
uint32_t used_stack;
|
||||
bool stack_check = 1;
|
||||
const size_t func_type_offset = is_closure ? offsetof(zend_closure, func.type) : offsetof(zend_function, type);
|
||||
|
||||
// REG0 -> zend_function
|
||||
// FCARG1 -> used_stack
|
||||
@@ -8484,15 +8485,11 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
|
||||
used_stack = (ZEND_CALL_FRAME_SLOT + opline->extended_value + ZEND_OBSERVER_ENABLED) * sizeof(zval);
|
||||
|
||||
| // if (EXPECTED(ZEND_USER_CODE(func->type))) {
|
||||
if (!is_closure) {
|
||||
| LOAD_32BIT_VAL FCARG1w, used_stack
|
||||
| // Check whether REG0 is an internal function.
|
||||
| ldrb TMP1w, [REG0, #offsetof(zend_function, type)]
|
||||
| TST_32_WITH_CONST TMP1w, 1, TMP2w
|
||||
| bne >1
|
||||
} else {
|
||||
| LOAD_32BIT_VAL FCARG1w, used_stack
|
||||
}
|
||||
| LOAD_32BIT_VAL FCARG1w, used_stack
|
||||
| // Check whether REG0 is an internal function.
|
||||
| ldrb TMP1w, [REG0, #func_type_offset]
|
||||
| TST_32_WITH_CONST TMP1w, 1, TMP2w
|
||||
| bne >1
|
||||
| // used_stack += (func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args)) * sizeof(zval);
|
||||
| LOAD_32BIT_VAL REG2w, opline->extended_value
|
||||
if (!is_closure) {
|
||||
|
||||
@@ -9072,6 +9072,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con
|
||||
{
|
||||
uint32_t used_stack;
|
||||
bool stack_check = 1;
|
||||
const size_t func_type_offset = is_closure ? offsetof(zend_closure, func.type) : offsetof(zend_function, type);
|
||||
|
||||
if (func) {
|
||||
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
|
||||
used_stack = (ZEND_CALL_FRAME_SLOT + opline->extended_value + ZEND_OBSERVER_ENABLED) * sizeof(zval);
|
||||
|
||||
| // if (EXPECTED(ZEND_USER_CODE(func->type))) {
|
||||
if (!is_closure) {
|
||||
| test byte [r0 + offsetof(zend_function, type)], 1
|
||||
| mov FCARG1a, used_stack
|
||||
| jnz >1
|
||||
} else {
|
||||
| mov FCARG1a, used_stack
|
||||
}
|
||||
| test byte [r0 + func_type_offset], 1
|
||||
| mov FCARG1a, used_stack
|
||||
| jnz >1
|
||||
| // used_stack += (func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args)) * sizeof(zval);
|
||||
| mov edx, opline->extended_value
|
||||
if (!is_closure) {
|
||||
|
||||
32
ext/opcache/tests/jit/gh17307.phpt
Normal file
32
ext/opcache/tests/jit/gh17307.phpt
Normal file
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
GH-17307 (Internal closure causes JIT failure)
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
simplexml
|
||||
bcmath
|
||||
--INI--
|
||||
opcache.jit=1254
|
||||
opcache.jit_hot_func=1
|
||||
opcache.jit_buffer_size=32M
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$simple = new SimpleXMLElement("<root><a/><b/></root>");
|
||||
|
||||
function run_loop($firstTerms, $closure) {
|
||||
foreach ($firstTerms as $firstTerm) {
|
||||
\debug_zval_dump($firstTerm);
|
||||
$closure($firstTerm, "10");
|
||||
}
|
||||
}
|
||||
|
||||
run_loop($simple, bcadd(...));
|
||||
echo "Done\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(SimpleXMLElement)#%d (0) refcount(3){
|
||||
}
|
||||
object(SimpleXMLElement)#%d (0) refcount(3){
|
||||
}
|
||||
Done
|
||||
Reference in New Issue
Block a user