diff options
-rw-r--r-- | Zend/zend_extensions.c | 68 | ||||
-rw-r--r-- | Zend/zend_extensions.h | 15 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 14 | ||||
-rw-r--r-- | ext/opcache/zend_persist.c | 2 | ||||
-rw-r--r-- | ext/opcache/zend_persist_calc.c | 2 |
5 files changed, 95 insertions, 6 deletions
diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index 00e4f659a0..bec776e68c 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -22,6 +22,7 @@ #include "zend_extensions.h" ZEND_API zend_llist zend_extensions; +ZEND_API uint32_t zend_extension_flags = 0; static int last_resource_number; int zend_load_extension(const char *path) @@ -137,6 +138,21 @@ int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle) zend_llist_add_element(&zend_extensions, &extension); + if (extension.op_array_ctor) { + zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR; + } + if (extension.op_array_dtor) { + zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR; + } + if (extension.op_array_handler) { + zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER; + } + if (extension.op_array_persist_calc) { + zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC; + } + if (extension.op_array_persist) { + zend_extension_flags |= ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST; + } /*fprintf(stderr, "Loaded %s, version %s\n", extension.name, extension.version);*/ #endif @@ -245,6 +261,58 @@ ZEND_API zend_extension *zend_get_extension(const char *extension_name) return NULL; } +typedef struct _zend_extension_persist_data { + zend_op_array *op_array; + size_t size; + char *mem; +} zend_extension_persist_data; + +static void zend_extension_op_array_persist_calc_handler(zend_extension *extension, zend_extension_persist_data *data) +{ + if (extension->op_array_persist_calc) { + data->size += extension->op_array_persist_calc(data->op_array); + } +} + +static void zend_extension_op_array_persist_handler(zend_extension *extension, zend_extension_persist_data *data) +{ + if (extension->op_array_persist) { + size_t size = extension->op_array_persist(data->op_array, data->mem); + if (size) { + data->mem = (void*)((char*)data->mem + size); + data->size += size; + } + } +} + +ZEND_API size_t zend_extensions_op_array_persist_calc(zend_op_array *op_array) +{ + if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC) { + zend_extension_persist_data data; + + data.op_array = op_array; + data.size = 0; + data.mem = NULL; + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_calc_handler, &data); + return data.size; + } + return 0; +} + +ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem) +{ + if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST) { + zend_extension_persist_data data; + + data.op_array = op_array; + data.size = 0; + data.mem = mem; + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_persist_handler, &data); + return data.size; + } + return 0; +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 8ef773badf..60d03aa43f 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -55,6 +55,8 @@ typedef void (*fcall_end_handler_func_t)(zend_op_array *op_array); typedef void (*op_array_ctor_func_t)(zend_op_array *op_array); typedef void (*op_array_dtor_func_t)(zend_op_array *op_array); +typedef size_t (*op_array_persist_calc_func_t)(zend_op_array *op_array); +typedef size_t (*op_array_persist_func_t)(zend_op_array *op_array, void *mem); struct _zend_extension { char *name; @@ -81,8 +83,8 @@ struct _zend_extension { int (*api_no_check)(int api_no); int (*build_id_check)(const char* build_id); - void *reserved3; - void *reserved4; + op_array_persist_calc_func_t op_array_persist_calc; + op_array_persist_func_t op_array_persist; void *reserved5; void *reserved6; void *reserved7; @@ -109,6 +111,13 @@ END_EXTERN_C() ZEND_API extern zend_llist zend_extensions; +ZEND_API extern uint32_t zend_extension_flags; + +#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR (1<<0) +#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR (1<<1) +#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_HANDLER (1<<2) +#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST_CALC (1<<3) +#define ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST (1<<4) void zend_extension_dtor(zend_extension *extension); ZEND_API void zend_append_version_info(const zend_extension *extension); @@ -120,6 +129,8 @@ BEGIN_EXTERN_C() ZEND_API int zend_load_extension(const char *path); ZEND_API int zend_register_extension(zend_extension *new_extension, DL_HANDLE handle); ZEND_API zend_extension *zend_get_extension(const char *extension_name); +ZEND_API size_t zend_extensions_op_array_persist_calc(zend_op_array *op_array); +ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem); END_EXTERN_C() #endif /* ZEND_EXTENSIONS_H */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 1a78148823..8abfd7a56c 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -99,7 +99,9 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array); + if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_CTOR) { + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array); + } } ZEND_API void destroy_zend_function(zend_function *function) @@ -391,8 +393,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) if (op_array->try_catch_array) { efree(op_array->try_catch_array); } - if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) { - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array); + if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_DTOR) { + if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) { + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array); + } } if (op_array->arg_info) { int32_t num_args = op_array->num_args; @@ -582,7 +586,9 @@ ZEND_API int pass_two(zend_op_array *op_array) zend_update_extended_info(op_array); } if (CG(compiler_options) & ZEND_COMPILE_HANDLE_OP_ARRAY) { - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array); + if (zend_extension_flags & ZEND_EXTENSIONS_HAVE_OP_ARRAY_PERSIST) { + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array); + } } if (CG(context).vars_size != op_array->last_var) { diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 8e37e6247b..1f5abb4652 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -667,6 +667,8 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } else { op_array->prototype = NULL; } + + ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem)))); } static void zend_persist_op_array(zval *zv) diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index d07e309faa..42d962b7cb 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -254,6 +254,8 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) ADD_INTERNED_STRING(op_array->vars[i], 0); } } + + ADD_SIZE(ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist_calc(op_array))); } static void zend_persist_op_array_calc(zval *zv) |