From 2b249d6e0c9241993930fd4a8992ece10193fa1e Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 12 Aug 2026 19:10:53 +0200 Subject: [PATCH] PFA: Extend local pointer map after loading PFA from SHM When loading a PFA from SHM we may need to extend the local pointer map because the PFA may use pointers higher than CG(map_ptr_last). Similar synchronization happens in inheritance cache or when loading whole scripts. --- .../partial_application/map_ptr_last.phpt | 58 +++++++++++++++++++ ext/opcache/ZendAccelerator.c | 3 + 2 files changed, 61 insertions(+) create mode 100644 Zend/tests/partial_application/map_ptr_last.phpt diff --git a/Zend/tests/partial_application/map_ptr_last.phpt b/Zend/tests/partial_application/map_ptr_last.phpt new file mode 100644 index 000000000000..1ee70d457358 --- /dev/null +++ b/Zend/tests/partial_application/map_ptr_last.phpt @@ -0,0 +1,58 @@ +--TEST-- +PFA and ZCSG(map_ptr_last) +--CREDITS-- +Ryan @ Calif.io +--EXTENSIONS-- +pcntl +--INI-- +opcache.file_update_protection=0 +--SKIPIF-- + +--FILE-- + CG(map_ptr_last) */ + var_dump(get_pfa()('ReflectionClass')); +} else { + /* Increment ZSCG(map_ptr_last) enough to mandate a realloc in other processes. + * We do so by compiling many functions that are guaranteed to allocate a map_ptr. */ + + $fd = fopen(__DIR__ . '/map_ptr_last.inc', 'w'); + fwrite($fd, "prop; }\n", $i); + } + fclose($fd); + + require __DIR__ . '/map_ptr_last.inc'; + + /* Compile a PFA */ + get_pfa()('ReflectionClass'); +} + +?> +--CLEAN-- + +--EXPECTF-- +object(ReflectionClass)#%d (1) { + ["name"]=> + string(15) "ReflectionClass" +} diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index cf62765d9e1d..efd608f93c58 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2073,6 +2073,9 @@ const zend_op_array *zend_accel_pfa_cache_get( zend_emit_recorded_errors_ex(persistent_script->num_warnings, persistent_script->warnings); } + if (ZCSG(map_ptr_last) > CG(map_ptr_last)) { + zend_map_ptr_extend(ZCSG(map_ptr_last)); + } } } else { op_array = zend_hash_find_ptr(&EG(partial_function_application_cache), key);