Skip to content

Commit 62ebe82

Browse files
committed
Separate internal and user function extension handles
This allows us to skip zend_init_internal_run_time_cache() when opcache is enabled. This function can be quite expensive. Closes GH-14252
1 parent 8094bd1 commit 62ebe82

File tree

7 files changed

+38
-2
lines changed

7 files changed

+38
-2
lines changed

UPGRADING.INTERNALS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ PHP 8.4 INTERNALS UPGRADE NOTES
8181
got each a new parameter returning an observer which must be called, if the
8282
removal happened during observer execution.
8383

84+
* zend_get_internal_function_extension_handle[s]() must now be used over
85+
zend_get_op_array_extension_handle[s]() when registering run_time_cache slots
86+
for internal functions. If you need a cache slot for both internal and user
87+
functions, you may obtain a slot for each through the corresponding function.
88+
8489

8590
========================
8691
2. Build system changes

Zend/zend_extensions.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
ZEND_API zend_llist zend_extensions;
2424
ZEND_API uint32_t zend_extension_flags = 0;
2525
ZEND_API int zend_op_array_extension_handles = 0;
26+
ZEND_API int zend_internal_function_extension_handles = 0;
2627
static int last_resource_number;
2728

2829
zend_result zend_load_extension(const char *path)
@@ -207,6 +208,7 @@ void zend_startup_extensions_mechanism(void)
207208
/* Startup extensions mechanism */
208209
zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
209210
zend_op_array_extension_handles = 0;
211+
zend_internal_function_extension_handles = 0;
210212
last_resource_number = 0;
211213
}
212214

@@ -301,8 +303,23 @@ ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int ha
301303
return handle;
302304
}
303305

306+
ZEND_API int zend_get_internal_function_extension_handle(const char *module_name)
307+
{
308+
int handle = zend_internal_function_extension_handles++;
309+
zend_add_system_entropy(module_name, "zend_get_internal_function_extension_handle", &zend_internal_function_extension_handles, sizeof(int));
310+
return handle;
311+
}
312+
313+
ZEND_API int zend_get_internal_function_extension_handles(const char *module_name, int handles)
314+
{
315+
int handle = zend_internal_function_extension_handles;
316+
zend_internal_function_extension_handles += handles;
317+
zend_add_system_entropy(module_name, "zend_get_internal_function_extension_handle", &zend_internal_function_extension_handles, sizeof(int));
318+
return handle;
319+
}
320+
304321
ZEND_API size_t zend_internal_run_time_cache_reserved_size(void) {
305-
return zend_op_array_extension_handles * sizeof(void *);
322+
return zend_internal_function_extension_handles * sizeof(void *);
306323
}
307324

308325
ZEND_API void zend_init_internal_run_time_cache(void) {

Zend/zend_extensions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ extern ZEND_API int zend_op_array_extension_handles;
116116
ZEND_API int zend_get_resource_handle(const char *module_name);
117117
ZEND_API int zend_get_op_array_extension_handle(const char *module_name);
118118
ZEND_API int zend_get_op_array_extension_handles(const char *module_name, int handles);
119+
ZEND_API int zend_get_internal_function_extension_handle(const char *module_name);
120+
ZEND_API int zend_get_internal_function_extension_handles(const char *module_name, int handles);
119121
ZEND_API void zend_extension_dispatch_message(int message, void *arg);
120122
END_EXTERN_C()
121123

Zend/zend_observer.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#include "zend_vm.h"
2525

2626
#define ZEND_OBSERVER_DATA(function) \
27-
ZEND_OP_ARRAY_EXTENSION((&(function)->common), zend_observer_fcall_op_array_extension)
27+
ZEND_OP_ARRAY_EXTENSION((&(function)->common), ZEND_USER_CODE((function)->type) \
28+
? zend_observer_fcall_op_array_extension : zend_observer_fcall_internal_function_extension)
2829

2930
#define ZEND_OBSERVER_NOT_OBSERVED ((void *) 2)
3031

@@ -40,6 +41,7 @@ zend_llist zend_observer_fiber_switch;
4041
zend_llist zend_observer_fiber_destroy;
4142

4243
int zend_observer_fcall_op_array_extension;
44+
int zend_observer_fcall_internal_function_extension;
4345
bool zend_observer_errors_observed;
4446
bool zend_observer_function_declared_observed;
4547
bool zend_observer_class_linked_observed;
@@ -64,6 +66,7 @@ ZEND_API void zend_observer_startup(void)
6466
zend_llist_init(&zend_observer_fiber_destroy, sizeof(zend_observer_fiber_destroy_handler), NULL, 1);
6567

6668
zend_observer_fcall_op_array_extension = -1;
69+
zend_observer_fcall_internal_function_extension = -1;
6770
}
6871

6972
ZEND_API void zend_observer_post_startup(void)
@@ -74,6 +77,9 @@ ZEND_API void zend_observer_post_startup(void)
7477
zend_observer_fcall_op_array_extension =
7578
zend_get_op_array_extension_handles("Zend Observer", (int) zend_observers_fcall_list.count * 2);
7679

80+
zend_observer_fcall_internal_function_extension =
81+
zend_get_internal_function_extension_handles("Zend Observer", (int) zend_observers_fcall_list.count * 2);
82+
7783
/* ZEND_CALL_TRAMPOLINE has SPEC(OBSERVER) but zend_init_call_trampoline_op()
7884
* is called before any extensions have registered as an observer. So we
7985
* adjust the offset to the observed handler when we know we need to observe. */

Zend/zend_observer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
BEGIN_EXTERN_C()
2828

2929
extern ZEND_API int zend_observer_fcall_op_array_extension;
30+
extern ZEND_API int zend_observer_fcall_internal_function_extension;
3031
extern ZEND_API bool zend_observer_errors_observed;
3132
extern ZEND_API bool zend_observer_function_declared_observed;
3233
extern ZEND_API bool zend_observer_class_linked_observed;
3334

35+
/* Omit zend_observer_fcall_internal_function_extension check, they are set at the same time. */
3436
#define ZEND_OBSERVER_ENABLED (zend_observer_fcall_op_array_extension != -1)
3537

3638
#define ZEND_OBSERVER_FCALL_BEGIN(execute_data) do { \

Zend/zend_vm_def.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8019,6 +8019,8 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
80198019
}
80208020

80218021
/* Uncaught exception */
8022+
8023+
/* Don't use ZEND_OBSERVER_ENABLED because it gets replaced by zend_vm_gen.php. */
80228024
if (zend_observer_fcall_op_array_extension != -1) {
80238025
zend_observer_fcall_end(execute_data, NULL);
80248026
}

Zend/zend_vm_execute.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)