php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch auto_filter_on_missing_lambdas.patch for APC Bug #52144Patch version 2012-11-02 12:18 UTC Return to Bug #52144 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: gopalv@php.netIndex: 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) */ } |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Sat Dec 14 16:01:26 2024 UTC |