Skip to content

Commit 329151e

Browse files
committed
Fix preloading edge case
1 parent cfd0bfb commit 329151e

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

ext/opcache/zend_persist.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -637,20 +637,26 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
637637
static void zend_persist_op_array(zval *zv)
638638
{
639639
zend_op_array *op_array = Z_PTR_P(zv);
640-
640+
zend_op_array *old_op_array;
641641
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
642-
op_array = Z_PTR_P(zv) = zend_shared_memdup(Z_PTR_P(zv), sizeof(zend_op_array));
643-
zend_persist_op_array_ex(op_array, NULL);
644-
if (!ZCG(current_persistent_script)->corrupted) {
645-
op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
646-
ZEND_MAP_PTR_NEW(op_array->run_time_cache);
647-
if (op_array->static_variables) {
648-
ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
642+
643+
old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
644+
if (!old_op_array) {
645+
op_array = Z_PTR_P(zv) = zend_shared_memdup_put(Z_PTR_P(zv), sizeof(zend_op_array));
646+
zend_persist_op_array_ex(op_array, NULL);
647+
if (!ZCG(current_persistent_script)->corrupted) {
648+
op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
649+
ZEND_MAP_PTR_NEW(op_array->run_time_cache);
650+
if (op_array->static_variables) {
651+
ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
652+
}
653+
} else {
654+
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ZCG(arena_mem));
655+
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*)));
656+
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
649657
}
650658
} else {
651-
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ZCG(arena_mem));
652-
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*)));
653-
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
659+
/* This can happen during preloading, if a dynamic function definition is declared. */
654660
}
655661
}
656662

ext/opcache/zend_persist_calc.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,17 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
299299
static void zend_persist_op_array_calc(zval *zv)
300300
{
301301
zend_op_array *op_array = Z_PTR_P(zv);
302-
303302
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
304-
ADD_SIZE(sizeof(zend_op_array));
305-
zend_persist_op_array_calc_ex(Z_PTR_P(zv));
306-
if (ZCG(current_persistent_script)->corrupted) {
307-
ADD_ARENA_SIZE(sizeof(void*));
303+
304+
if (!zend_shared_alloc_get_xlat_entry(op_array)) {
305+
zend_shared_alloc_register_xlat_entry(op_array, op_array);
306+
ADD_SIZE(sizeof(zend_op_array));
307+
zend_persist_op_array_calc_ex(op_array);
308+
if (ZCG(current_persistent_script)->corrupted) {
309+
ADD_ARENA_SIZE(sizeof(void*));
310+
}
311+
} else {
312+
/* This can happen during preloading, if a dynamic function definition is declared. */
308313
}
309314
}
310315

0 commit comments

Comments
 (0)