summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-09-25 11:50:38 +0300
committerDmitry Stogov <dmitry@zend.com>2015-09-25 11:50:38 +0300
commita05fc48055dee5562b97f8ea8c598186852f2cea (patch)
treebcaed579ab47a6a04166eaeab5960c834d93531c /Zend
parentf509706318bcd7198faff747f0eab326f2953524 (diff)
downloadphp-git-a05fc48055dee5562b97f8ea8c598186852f2cea.tar.gz
Extended zend_extension API to allow storing additional data associated with op_arrays in opcache SHM. (op_array->reserved[])
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_extensions.c68
-rw-r--r--Zend/zend_extensions.h15
-rw-r--r--Zend/zend_opcode.c14
3 files changed, 91 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) {