|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
Patch bug52144_new.patch for APC Bug #52144Patch version 2012-11-07 07:03 UTC Return to Bug #52144 | Download this patchThis patch is obsolete Obsoleted by patches:
Developer: laruence@php.net
Index: apc_main.c
===================================================================
--- apc_main.c (revision 328266)
+++ apc_main.c (working copy)
@@ -361,15 +361,56 @@
}
/* }}} */
+void apc_hook_func_table_dtor(void *pDest) {
+ zend_function *func = (zend_function *)pDest;
+ zend_hash_next_index_insert(APCG(compiler_hook_func_table), func->common.function_name, strlen(func->common.function_name) + 1, NULL);
+ return zend_function_dtor(pDest);
+}
+
+void apc_hook_class_table_dtor(void *pDest) {
+ /* not implemented yet */
+ return destroy_zend_class(pDest);
+}
+
/* {{{ apc_compile_cache_entry */
zend_bool apc_compile_cache_entry(apc_cache_key_t *key, zend_file_handle* h, int type, time_t t, zend_op_array** op_array, apc_cache_entry_t** cache_entry TSRMLS_DC) {
- int num_functions, num_classes;
+ int num_functions, num_classes, modified_functions, modified_classes;
apc_function_t* alloc_functions;
zend_op_array* alloc_op_array;
apc_class_t* alloc_classes;
char *path;
apc_context_t ctxt;
+ HashTable *old_hook_class_table = NULL, *old_hook_func_table = NULL;
+ HashTable *target_class_table = CG(class_table);
+ HashTable *target_func_table = CG(function_table);
+ target_func_table->pDestructor = apc_hook_func_table_dtor;
+ target_class_table->pDestructor = apc_hook_class_table_dtor;
+#define UNLOAD_COMPILER_TABLES_HOOKER() \
+ do { \
+ zend_hash_destroy(APCG(compiler_hook_func_table)); \
+ FREE_HASHTABLE(APCG(compiler_hook_func_table)); \
+ zend_hash_destroy(APCG(compiler_hook_class_table)); \
+ FREE_HASHTABLE(APCG(compiler_hook_class_table)); \
+ APCG(compiler_hook_func_table) = old_hook_func_table; \
+ APCG(compiler_hook_class_table) = old_hook_class_table; \
+ target_class_table->pDestructor = ZEND_CLASS_DTOR; \
+ target_func_table->pDestructor = ZEND_FUNCTION_DTOR; \
+ } while (0);
+
+ if (APCG(compiler_hook_func_table)) {
+ old_hook_func_table = APCG(compiler_hook_func_table);
+ }
+
+ if (APCG(compiler_hook_class_table)) {
+ old_hook_class_table = APCG(compiler_hook_class_table);
+ }
+
+ ALLOC_HASHTABLE(APCG(compiler_hook_func_table));
+ zend_hash_init(APCG(compiler_hook_func_table), 8, NULL, NULL, 0);
+ ALLOC_HASHTABLE(APCG(compiler_hook_class_table));
+ zend_hash_init(APCG(compiler_hook_class_table), 8, NULL, NULL, 0);
+
/* remember how many functions and classes existed before compilation */
num_functions = zend_hash_num_elements(CG(function_table));
num_classes = zend_hash_num_elements(CG(class_table));
@@ -379,12 +420,14 @@
* a failure. We should not return prior to this line. */
*op_array = old_compile_file(h, type TSRMLS_CC);
if (*op_array == NULL) {
+ UNLOAD_COMPILER_TABLES_HOOKER();
return FAILURE;
}
ctxt.pool = apc_pool_create(APC_MEDIUM_POOL, apc_sma_malloc, apc_sma_free,
apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
if (!ctxt.pool) {
+ UNLOAD_COMPILER_TABLES_HOOKER();
apc_warning("Unable to allocate memory for pool." TSRMLS_CC);
return FAILURE;
}
@@ -429,6 +472,15 @@
goto freepool;
}
+ if ((modified_functions = zend_hash_num_elements(APCG(compiler_hook_func_table)))) {
+ if (!apc_copy_modified_functions(APCG(compiler_hook_func_table), alloc_functions, num_functions, &ctxt TSRMLS_CC)) {
+ goto freepool;
+ }
+ }
+
+ if (zend_hash_num_elements(APCG(compiler_hook_class_table))) {
+ }
+
path = h->opened_path;
if(!path && key->type == APC_CACHE_KEY_FPFILE) path = (char*)key->data.fpfile.fullpath;
if(!path) path=h->filename;
@@ -438,10 +490,12 @@
if(!(*cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes, &ctxt TSRMLS_CC))) {
goto freepool;
}
-
+
+ UNLOAD_COMPILER_TABLES_HOOKER();
return SUCCESS;
freepool:
+ UNLOAD_COMPILER_TABLES_HOOKER();
apc_pool_destroy(ctxt.pool TSRMLS_CC);
ctxt.pool = NULL;
Index: apc_compile.c
===================================================================
--- apc_compile.c (revision 328266)
+++ apc_compile.c (working copy)
@@ -1452,7 +1452,7 @@
int new_count; /* number of new functions in table */
int i;
apc_pool* pool = ctxt->pool;
-
+
new_count = zend_hash_num_elements(CG(function_table)) - old_count;
assert(new_count >= 0);
@@ -1497,6 +1497,44 @@
}
/* }}} */
+/* {{{ apc_copy_modified_functions */
+apc_function_t* apc_copy_modified_functions(HashTable *funcs, apc_function_t *alloc_functions, int num_functions, apc_context_t *ctxt TSRMLS_DC) {
+ HashPosition pos;
+ zend_function *func;
+ apc_function_t *array;
+ int modified_count = zend_hash_num_elements(funcs);
+ int index = zend_hash_num_elements(CG(function_table)) - num_functions;
+
+ CHECK(array = (apc_function_t*) apc_pool_alloc(ctxt->pool, (sizeof(apc_function_t) * (index + modified_count + 1))));
+ memcpy(array, alloc_functions, (sizeof(apc_function_t) * (index + 1)));
+
+ zend_hash_internal_pointer_reset_ex(CG(function_table), &pos);
+ while (zend_hash_get_current_data_ex(CG(function_table), (void **)&func, &pos) == SUCCESS) {
+ if (func->type == ZEND_USER_FUNCTION) {
+ char* key;
+ uint key_size;
+ HashPosition nPos;
+ char *function_name;
+
+ zend_hash_internal_pointer_reset_ex(funcs, &nPos);
+ while (zend_hash_get_current_data_ex(funcs, (void **)&function_name, &nPos) == SUCCESS) {
+ if (strcmp(function_name, func->common.function_name) == 0) {
+ zend_hash_get_current_key_ex(CG(function_table), &key, &key_size, NULL, 0, &pos);
+ CHECK(alloc_functions[index].name = apc_pmemcpy(key, (int) key_size, ctxt->pool TSRMLS_CC));
+ alloc_functions[index].name_len = (int) key_size-1;
+ CHECK(alloc_functions[index].function = my_copy_function(NULL, func, ctxt TSRMLS_CC));
+ index++;
+ }
+ zend_hash_move_forward_ex(funcs, &nPos);
+ }
+ }
+ zend_hash_move_forward_ex(CG(function_table), &pos);
+ }
+ alloc_functions[index].function = NULL;
+ return alloc_functions;
+}
+/* }}} */
+
/* {{{ apc_copy_new_classes */
apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t *ctxt TSRMLS_DC)
{
Index: apc_compile.h
===================================================================
--- apc_compile.h (revision 328266)
+++ apc_compile.h (working copy)
@@ -91,6 +91,7 @@
extern zend_op_array* apc_copy_op_array(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC);
extern zend_class_entry* apc_copy_class_entry(zend_class_entry* dst, zend_class_entry* src, apc_context_t* ctxt TSRMLS_DC);
extern apc_function_t* apc_copy_new_functions(int old_count, apc_context_t* ctxt TSRMLS_DC);
+extern apc_function_t* apc_copy_modified_functions(HashTable *funcs, apc_function_t *alloc_functions, int num_functions, apc_context_t *ctxt TSRMLS_DC);
extern apc_class_t* apc_copy_new_classes(zend_op_array* op_array, int old_count, apc_context_t* ctxt TSRMLS_DC);
extern zval* apc_copy_zval(zval* dst, const zval* src, apc_context_t* ctxt TSRMLS_DC);
#ifdef ZEND_ENGINE_2_4
Index: apc_globals.h
===================================================================
--- apc_globals.h (revision 328266)
+++ apc_globals.h (working copy)
@@ -124,6 +124,8 @@
#endif
char *serializer_name; /* the serializer config option */
apc_serializer_t *serializer;/* the actual serializer in use */
+ HashTable *compiler_hook_func_table;
+ HashTable *compiler_hook_class_table;
ZEND_END_MODULE_GLOBALS(apc)
/* (the following declaration is defined in php_apc.c) */
|
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 14:00:01 2025 UTC |