|
56 | 56 |
|
57 | 57 | #ifdef HAVE_JIT
|
58 | 58 | # include "jit/zend_jit.h"
|
| 59 | +# include "Optimizer/zend_func_info.h" |
| 60 | +# include "Optimizer/zend_call_graph.h" |
59 | 61 | #endif
|
60 | 62 |
|
61 | 63 | #ifndef ZEND_WIN32
|
@@ -4471,6 +4473,39 @@ static void preload_load(size_t orig_map_ptr_static_last)
|
4471 | 4473 | }
|
4472 | 4474 | }
|
4473 | 4475 |
|
| 4476 | +#if HAVE_JIT |
| 4477 | +static void zend_accel_clear_call_graph_ptrs(zend_op_array *op_array) |
| 4478 | +{ |
| 4479 | + ZEND_ASSERT(ZEND_USER_CODE(op_array->type)); |
| 4480 | + zend_func_info *info = ZEND_FUNC_INFO(op_array); |
| 4481 | + if (info) { |
| 4482 | + info->caller_info = NULL; |
| 4483 | + info->callee_info = NULL; |
| 4484 | + } |
| 4485 | +} |
| 4486 | + |
| 4487 | +static void accel_reset_arena_info(zend_persistent_script *script) |
| 4488 | +{ |
| 4489 | + zend_op_array *op_array; |
| 4490 | + zend_class_entry *ce; |
| 4491 | + |
| 4492 | + zend_accel_clear_call_graph_ptrs(&script->script.main_op_array); |
| 4493 | + ZEND_HASH_MAP_FOREACH_PTR(&script->script.function_table, op_array) { |
| 4494 | + zend_accel_clear_call_graph_ptrs(op_array); |
| 4495 | + } ZEND_HASH_FOREACH_END(); |
| 4496 | + ZEND_HASH_MAP_FOREACH_PTR(&script->script.class_table, ce) { |
| 4497 | + ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, op_array) { |
| 4498 | + if (op_array->scope == ce |
| 4499 | + && op_array->type == ZEND_USER_FUNCTION |
| 4500 | + && !(op_array->fn_flags & ZEND_ACC_ABSTRACT) |
| 4501 | + && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) { |
| 4502 | + zend_accel_clear_call_graph_ptrs(op_array); |
| 4503 | + } |
| 4504 | + } ZEND_HASH_FOREACH_END(); |
| 4505 | + } ZEND_HASH_FOREACH_END(); |
| 4506 | +} |
| 4507 | +#endif |
| 4508 | + |
4474 | 4509 | static zend_result accel_preload(const char *config, bool in_child)
|
4475 | 4510 | {
|
4476 | 4511 | zend_file_handle file_handle;
|
@@ -4683,6 +4718,18 @@ static zend_result accel_preload(const char *config, bool in_child)
|
4683 | 4718 | } ZEND_HASH_FOREACH_END();
|
4684 | 4719 | ZCSG(saved_scripts)[i] = NULL;
|
4685 | 4720 |
|
| 4721 | +#if HAVE_JIT |
| 4722 | + /* During persisting, the JIT may trigger and fill in the call graph. |
| 4723 | + * The call graph info is allocated on the arena which will be gone after preloading. |
| 4724 | + * To prevent invalid accesses during normal requests, the arena data should be cleared. |
| 4725 | + * This has to be done after all scripts have been persisted because shared op arrays between |
| 4726 | + * scripts can change the call graph. */ |
| 4727 | + accel_reset_arena_info(ZCSG(preload_script)); |
| 4728 | + for (zend_persistent_script **scripts = ZCSG(saved_scripts); *scripts; scripts++) { |
| 4729 | + accel_reset_arena_info(*scripts); |
| 4730 | + } |
| 4731 | +#endif |
| 4732 | + |
4686 | 4733 | zend_shared_alloc_save_state();
|
4687 | 4734 | accel_interned_strings_save_state();
|
4688 | 4735 |
|
|
0 commit comments