Skip to content

Commit a05fc48

Browse files
committed
Extended zend_extension API to allow storing additional data associated with op_arrays in opcache SHM. (op_array->reserved[])
1 parent f509706 commit a05fc48

File tree

5 files changed

+95
-6
lines changed

5 files changed

+95
-6
lines changed

Diff for: Zend/zend_extensions.c

+68
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "zend_extensions.h"
2323

2424
ZEND_API zend_llist zend_extensions;
25+
ZEND_API uint32_t zend_extension_flags = 0;
2526
static int last_resource_number;
2627

2728
int zend_load_extension(const char *path)
@@ -137,6 +138,21 @@ int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle)
137138

138139
zend_llist_add_element(&zend_extensions, &extension);
139140

141+
if (extension.op_array_ctor) {
142+
zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR;
143+
}
144+
if (extension.op_array_dtor) {
145+
zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR;
146+
}
147+
if (extension.op_array_handler) {
148+
zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER;
149+
}
150+
if (extension.op_array_persist_calc) {
151+
zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC;
152+
}
153+
if (extension.op_array_persist) {
154+
zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST;
155+
}
140156
/*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/
141157
#endif
142158

@@ -245,6 +261,58 @@ ZEND_API zend_extension *zend_get_extension(const char *extension_name)
245261
return NULL;
246262
}
247263

264+
typedef struct _zend_extension_persist_data {
265+
zend_op_array *op_array;
266+
size_t size;
267+
char *mem;
268+
} zend_extension_persist_data;
269+
270+
static void zend_extension_op_array_persist_calc_handler(zend_extension *extension, zend_extension_persist_data *data)
271+
{
272+
if (extension->op_array_persist_calc) {
273+
data->size += extension->op_array_persist_calc(data->op_array);
274+
}
275+
}
276+
277+
static void zend_extension_op_array_persist_handler(zend_extension *extension, zend_extension_persist_data *data)
278+
{
279+
if (extension->op_array_persist) {
280+
size_t size = extension->op_array_persist(data->op_array, data->mem);
281+
if (size) {
282+
data->mem = (void*)((char*)data->mem + size);
283+
data->size += size;
284+
}
285+
}
286+
}
287+
288+
ZEND_API size_t zend_extensions_op_array_persist_calc(zend_op_array *op_array)
289+
{
290+
if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC) {
291+
zend_extension_persist_data data;
292+
293+
data.op_array = op_array;
294+
data.size = 0;
295+
data.mem = NULL;
296+
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_calc_handler, &data);
297+
return data.size;
298+
}
299+
return 0;
300+
}
301+
302+
ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem)
303+
{
304+
if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST) {
305+
zend_extension_persist_data data;
306+
307+
data.op_array = op_array;
308+
data.size = 0;
309+
data.mem = mem;
310+
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_handler, &data);
311+
return data.size;
312+
}
313+
return 0;
314+
}
315+
248316
/*
249317
* Local variables:
250318
* tab-width: 4

Diff for: Zend/zend_extensions.h

+13-2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ typedef void (*fcall_end_handler_func_t)(zend_op_array *op_array);
5555

5656
typedef void (*op_array_ctor_func_t)(zend_op_array *op_array);
5757
typedef void (*op_array_dtor_func_t)(zend_op_array *op_array);
58+
typedef size_t (*op_array_persist_calc_func_t)(zend_op_array *op_array);
59+
typedef size_t (*op_array_persist_func_t)(zend_op_array *op_array, void *mem);
5860

5961
struct _zend_extension {
6062
char *name;
@@ -81,8 +83,8 @@ struct _zend_extension {
8183

8284
int (*api_no_check)(int api_no);
8385
int (*build_id_check)(const char* build_id);
84-
void *reserved3;
85-
void *reserved4;
86+
op_array_persist_calc_func_t op_array_persist_calc;
87+
op_array_persist_func_t op_array_persist;
8688
void *reserved5;
8789
void *reserved6;
8890
void *reserved7;
@@ -109,6 +111,13 @@ END_EXTERN_C()
109111

110112

111113
ZEND_API extern zend_llist zend_extensions;
114+
ZEND_API extern uint32_t zend_extension_flags;
115+
116+
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR (1<<0)
117+
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR (1<<1)
118+
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER (1<<2)
119+
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC (1<<3)
120+
#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST (1<<4)
112121

113122
void zend_extension_dtor(zend_extension *extension);
114123
ZEND_API void zend_append_version_info(const zend_extension *extension);
@@ -120,6 +129,8 @@ BEGIN_EXTERN_C()
120129
ZEND_API int zend_load_extension(const char *path);
121130
ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle);
122131
ZEND_API zend_extension *zend_get_extension(const char *extension_name);
132+
ZEND_API size_t zend_extensions_op_array_persist_calc(zend_op_array *op_array);
133+
ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem);
123134
END_EXTERN_C()
124135

125136
#endif /* ZEND_EXTENSIONS_H */

Diff for: Zend/zend_opcode.c

+10-4
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
9999

100100
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
101101

102-
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array);
102+
if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR) {
103+
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array);
104+
}
103105
}
104106

105107
ZEND_API void destroy_zend_function(zend_function *function)
@@ -391,8 +393,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
391393
if (op_array->try_catch_array) {
392394
efree(op_array->try_catch_array);
393395
}
394-
if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
395-
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array);
396+
if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR) {
397+
if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
398+
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array);
399+
}
396400
}
397401
if (op_array->arg_info) {
398402
int32_t num_args = op_array->num_args;
@@ -582,7 +586,9 @@ ZEND_API int pass_two(zend_op_array *op_array)
582586
zend_update_extended_info(op_array);
583587
}
584588
if (CG(compiler_options) & ZEND_COMPILE_HANDLE_OP_ARRAY) {
585-
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array);
589+
if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST) {
590+
zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array);
591+
}
586592
}
587593

588594
if (CG(context).vars_size != op_array->last_var) {

Diff for: ext/opcache/zend_persist.c

+2
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
667667
} else {
668668
op_array->prototype = NULL;
669669
}
670+
671+
ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem))));
670672
}
671673

672674
static void zend_persist_op_array(zval *zv)

Diff for: ext/opcache/zend_persist_calc.c

+2
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
254254
ADD_INTERNED_STRING(op_array->vars[i], 0);
255255
}
256256
}
257+
258+
ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array)));
257259
}
258260

259261
static void zend_persist_op_array_calc(zval *zv)

0 commit comments

Comments
 (0)