php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #52144
Patch tracing_modified_functions_classes.patch revision 2012-11-08 14:32 UTC by laruence@php.net
Patch bug52144_new.patch revision 2012-11-07 10:58 UTC by laruence@php.net
revision 2012-11-07 07:03 UTC by laruence@php.net
Patch autofilter_missing_funcs.patch revision 2012-11-03 14:59 UTC by gopalv@php.net
Patch auto_filter_on_missing_lambdas.patch revision 2012-11-02 12:18 UTC by gopalv@php.net
Patch bug52144.patch revision 2012-11-02 04:32 UTC by laruence@php.net
revision 2012-11-01 03:10 UTC by laruence@php.net

Patch auto_filter_on_missing_lambdas.patch for APC Bug #52144

Patch version 2012-11-02 12:18 UTC

Return to Bug #52144 | Download this patch
This patch is obsolete

Obsoleted by patches:

Patch Revisions:

Developer: gopalv@php.net

Index: apc_compile.c
===================================================================
--- apc_compile.c	(revision 328140)
+++ apc_compile.c	(working copy)
@@ -1323,6 +1323,11 @@
                     }
                 }
                 break;
+#ifdef ZEND_ENGINE_2_4
+            case  ZEND_DECLARE_LAMBDA_FUNCTION:
+                flags->lambdas = 1;
+            break;
+#endif
             default:
 #ifdef ZEND_ENGINE_2_4
                 if((zo->op1_type == IS_CONST &&
@@ -1485,7 +1490,6 @@
                                      NULL);
 
         zend_hash_get_current_data(CG(function_table), (void**) &fun);
-
         CHECK(array[i].name = apc_pmemcpy(key, (int) key_size, pool TSRMLS_CC));
         array[i].name_len = (int) key_size-1;
         CHECK(array[i].function = my_copy_function(NULL, fun, ctxt TSRMLS_CC));
@@ -1597,6 +1601,11 @@
                         }
 #endif
 
+#ifdef ZEND_ENGINE_2_4
+# define APC_CHECK_MISSING_LAMBDA(op1, tmp) \
+    (zend_hash_find(CG(function_table), Z_STRVAL_P(op1.zv), Z_STRLEN_P(op1.zv), (void *) &tmp) == FAILURE)
+#endif
+
 /* {{{ my_prepare_op_array_for_execution */
 static int my_prepare_op_array_for_execution(zend_op_array* dst, zend_op_array* src, apc_context_t* ctxt TSRMLS_DC) 
 {
@@ -1613,6 +1622,7 @@
     int needcopy = flags ? flags->deep_copy : 1;
     /* auto_globals_jit was not in php4 */
     int do_prepare_fetch_global = PG(auto_globals_jit) && (flags == NULL || flags->unknown_global);
+    int has_lambdas = flags->lambdas;
 
 #define FETCH_AUTOGLOBAL(member) do { \
     if(flags && flags->member == 1) { \
@@ -1724,6 +1734,16 @@
                         APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
                     }
                     break;
+#ifdef ZEND_ENGINE_2_4
+                case ZEND_DECLARE_LAMBDA_FUNCTION:
+                    if(has_lambdas) {
+                        zend_op_array *tmp = NULL;
+                        if(APC_CHECK_MISSING_LAMBDA(zo->op1, tmp)) {
+                            return 0;
+                        }
+                    }
+                    break;
+#endif
                 default:
                     break;
             }
@@ -1732,18 +1752,27 @@
             dzo++;
         }
     } else {  /* !needcopy */
-        /* The fetch is only required if auto_globals_jit=1  */
-        if(do_prepare_fetch_global)
+        if(do_prepare_fetch_global || has_lambdas)
         {
             zo = src->opcodes;
             while(i > 0) {
 
-                if(zo->opcode == ZEND_FETCH_R ||
+                /* The fetch is only required if auto_globals_jit=1  */
+                if(do_prepare_fetch_global 
+                  && (zo->opcode == ZEND_FETCH_R ||
                    zo->opcode == ZEND_FETCH_W ||
                    zo->opcode == ZEND_FETCH_IS ||
                    zo->opcode == ZEND_FETCH_FUNC_ARG
-                  ) {
+                )) {
                     APC_PREPARE_FETCH_GLOBAL_FOR_EXECUTION();
+                #ifdef ZEND_ENGINE_2_4
+                } else if(has_lambdas
+                  && zo->opcode == ZEND_DECLARE_LAMBDA_FUNCTION) {
+                    void *tmp;
+                    if(APC_CHECK_MISSING_LAMBDA(zo->op1, tmp)) {
+                        return 0;
+                    }
+                #endif
                 }
 
                 i--;
@@ -1768,7 +1797,9 @@
                                       sizeof(src->refcount[0]),
                                       ctxt->pool TSRMLS_CC);
 
-    my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC);
+    if(!my_prepare_op_array_for_execution(dst,src, ctxt TSRMLS_CC)) {
+        return NULL;
+    }
 
     return dst;
 }
@@ -1790,8 +1821,10 @@
 
     dst = (zend_function*) emalloc(sizeof(src[0]));
     memcpy(dst, src, sizeof(src[0]));
-    apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC);
-    return dst;
+    if(apc_copy_op_array_for_execution(&(dst->op_array), &(src->op_array), ctxt TSRMLS_CC)) {
+        return dst;
+    }
+    return NULL;
 }
 /* }}} */
 
Index: apc_compile.h
===================================================================
--- apc_compile.h	(revision 328139)
+++ apc_compile.h	(working copy)
@@ -67,6 +67,7 @@
 struct apc_opflags_t {
     unsigned int has_jumps      : 1; /* has jump offsets */
     unsigned int deep_copy      : 1; /* needs deep copy */
+    unsigned int lambdas        : 1; /* declares lambdas */
 
     /* autoglobal bits */
     unsigned int _POST          : 1;
Index: apc_main.c
===================================================================
--- apc_main.c	(revision 328143)
+++ apc_main.c	(working copy)
@@ -74,6 +74,11 @@
     int status;
 	zend_function *func = apc_copy_function_for_execution(fn.function, ctxt TSRMLS_CC);
 
+    if(func == NULL) {
+        return (FAILURE-1); // massive failure
+    }
+
+
     status = zend_hash_add(EG(function_table), fn.name, fn.name_len+1, func, sizeof(zend_function), NULL);
     efree(func);
 
@@ -85,6 +90,21 @@
 }
 /* }}} */
 
+/* {{{ uninstall_function */
+static int uninstall_function(apc_function_t fn TSRMLS_DC)
+{
+    int status;
+
+    status = zend_hash_del(EG(function_table),
+                           fn.name,
+                           fn.name_len+1);
+    if (status == FAILURE) {
+        apc_error("Cannot delete function %s" TSRMLS_CC, fn.name);
+    }
+    return status;
+}
+/* }}} */
+
 /* {{{ apc_lookup_function_hook */
 int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) {
     apc_function_t *fn;
@@ -315,8 +335,10 @@
                                         int type,
                                         apc_context_t* ctxt TSRMLS_DC)
 {
+    zend_op_array *op_array;
     apc_cache_entry_t* cache_entry;
-    int i, ii;
+    int i=0, ii;
+    int j=0, jj;
 
     cache_entry = (apc_cache_entry_t*) apc_stack_top(APCG(cache_stack));
     assert(cache_entry != NULL);
@@ -332,19 +354,29 @@
 
     if (cache_entry->data.file.functions) {
         int lazy_functions = APCG(lazy_functions);
-        for (i = 0; cache_entry->data.file.functions[i].function != NULL; i++) {
-            install_function(cache_entry->data.file.functions[i], ctxt, lazy_functions TSRMLS_CC);
+        for (j = 0; cache_entry->data.file.functions[j].function != NULL; j++) {
+            if(install_function(cache_entry->data.file.functions[j], ctxt, lazy_functions TSRMLS_CC) < FAILURE) {
+                goto default_compile;
+            }
         }
     }
 
-    apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
+    op_array = apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
 
+    if(op_array) {
+        apc_do_halt_compiler_register(cache_entry->data.file.filename, cache_entry->data.file.halt_offset TSRMLS_CC);
+        return op_array;
+    }
+    /* fall through to default_compile */
 
-    return apc_copy_op_array_for_execution(NULL, cache_entry->data.file.op_array, ctxt TSRMLS_CC);
-
 default_compile:
 
-    /* XXX more cleanup in uninstall class, and uninstall_function() should be here too */
+    if(cache_entry->data.file.functions) {
+        for(jj = 0; jj < j ; jj++) {
+            uninstall_function(cache_entry->data.file.functions[jj] TSRMLS_CC);
+        }
+    }
+    /* XXX more cleanup in uninstall class */
     if(cache_entry->data.file.classes) {
         for(ii = 0; ii < i ; ii++) {
             uninstall_class(cache_entry->data.file.classes[ii] TSRMLS_CC);
@@ -421,7 +453,6 @@
     if(!(alloc_op_array = apc_copy_op_array(NULL, *op_array, &ctxt TSRMLS_CC))) {
         goto freepool;
     }
-
     if(!(alloc_functions = apc_copy_new_functions(num_functions, &ctxt TSRMLS_CC))) {
         goto freepool;
     }
@@ -438,7 +469,7 @@
     if(!(*cache_entry = apc_cache_make_file_entry(path, alloc_op_array, alloc_functions, alloc_classes, &ctxt TSRMLS_CC))) {
         goto freepool;
     }
-
+    
     return SUCCESS;
 
 freepool:
@@ -520,6 +551,7 @@
                             (void *)&dummy, sizeof(int), NULL);
 
         apc_stack_push(APCG(cache_stack), cache_entry TSRMLS_CC);
+        int num_functions = zend_hash_num_elements(CG(function_table));
         op_array = cached_compile(h, type, &ctxt TSRMLS_CC);
 
         if(op_array) {
@@ -544,6 +576,7 @@
             apc_warning("Autofiltering %s" TSRMLS_CC, 
                             (h->opened_path ? h->opened_path : h->filename));
             apc_warning("Recompiling %s" TSRMLS_CC, cache_entry->data.file.filename);
+            ctxt.force_update = 1;
         }
         /* TODO: check what happens with EG(included_files) */
     }
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 14 16:01:26 2024 UTC