|
57 | 57 |
|
58 | 58 | #ifdef HAVE_JIT
|
59 | 59 | # include "jit/zend_jit.h"
|
| 60 | +# include "Optimizer/zend_func_info.h" |
| 61 | +# include "Optimizer/zend_call_graph.h" |
60 | 62 | #endif
|
61 | 63 |
|
62 | 64 | #ifndef ZEND_WIN32
|
@@ -4537,6 +4539,39 @@ static void preload_load(size_t orig_map_ptr_static_last)
|
4537 | 4539 | }
|
4538 | 4540 | }
|
4539 | 4541 |
|
| 4542 | +#if HAVE_JIT |
| 4543 | +static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array) |
| 4544 | +{ |
| 4545 | + ZEND_ASSERT(ZEND_USER_CODE(op_array->type)); |
| 4546 | + zend_func_info *info = ZEND_FUNC_INFO(op_array); |
| 4547 | + if (info) { |
| 4548 | + info->caller_info = NULL; |
| 4549 | + info->callee_info = NULL; |
| 4550 | + } |
| 4551 | +} |
| 4552 | + |
| 4553 | +static void accel_reset_arena_info(zend_persistent_script *script) |
| 4554 | +{ |
| 4555 | + zend_op_array *op_array; |
| 4556 | + zend_class_entry *ce; |
| 4557 | + |
| 4558 | + zend_accel_clear_call_graph_ptrs(&script->script.main_op_array); |
| 4559 | + ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) { |
| 4560 | + zend_accel_clear_call_graph_ptrs(op_array); |
| 4561 | + } ZEND_HASH_FOREACH_END(); |
| 4562 | + ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) { |
| 4563 | + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { |
| 4564 | + if (op_array->scope == ce |
| 4565 | + && op_array->type == ZEND_USER_FUNCTION |
| 4566 | + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) |
| 4567 | + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { |
| 4568 | + zend_accel_clear_call_graph_ptrs(op_array); |
| 4569 | + } |
| 4570 | + } ZEND_HASH_FOREACH_END(); |
| 4571 | + } ZEND_HASH_FOREACH_END(); |
| 4572 | +} |
| 4573 | +#endif |
| 4574 | + |
4540 | 4575 | static zend_result accel_preload(const char *config, bool in_child)
|
4541 | 4576 | {
|
4542 | 4577 | zend_file_handle file_handle;
|
@@ -4749,6 +4784,18 @@ static zend_result accel_preload(const char *config, bool in_child)
|
4749 | 4784 | } ZEND_HASH_FOREACH_END();
|
4750 | 4785 | ZCSG(saved_scripts)[i] = NULL;
|
4751 | 4786 |
|
| 4787 | +#if HAVE_JIT |
| 4788 | + /* During persisting, the JIT may trigger and fill in the call graph. |
| 4789 | + * The call graph info is allocated on the arena which will be gone after preloading. |
| 4790 | + * To prevent invalid accesses during normal requests, the arena data should be cleared. |
| 4791 | + * This has to be done after all scripts have been persisted because shared op arrays between |
| 4792 | + * scripts can change the call graph. */ |
| 4793 | + accel_reset_arena_info(ZCSG(preload_script)); |
| 4794 | + for (zend_persistent_script **scripts = ZCSG(saved_scripts); *scripts; scripts++) { |
| 4795 | + accel_reset_arena_info(*scripts); |
| 4796 | + } |
| 4797 | +#endif |
| 4798 | + |
4752 | 4799 | zend_shared_alloc_save_state();
|
4753 | 4800 | accel_interned_strings_save_state();
|
4754 | 4801 |
|
|
0 commit comments