php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch gc-closure.diff for Performance problem Bug #60139Patch version 2011-10-31 11:04 UTC Return to Bug #60139 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:Developer: dmitry@php.netIndex: php5.3/Zend/zend_gc.c =================================================================== --- php5.3/Zend/zend_gc.c (revision 318599) +++ php5.3/Zend/zend_gc.c (working copy) @@ -21,6 +21,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_closures.h" #define GC_ROOT_BUFFER_MAX_ENTRIES 10000 @@ -282,11 +283,20 @@ GC_SET_BLACK(obj->buffered); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; } } } else if (Z_TYPE_P(pz) == IS_ARRAY) { @@ -317,11 +327,20 @@ GC_SET_BLACK(obj->buffered); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; while (p != NULL) { pz = *(zval**)p->pData; if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { @@ -354,11 +373,20 @@ GC_SET_COLOR(obj->buffered, GC_GREY); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; } } } else if (Z_TYPE_P(pz) == IS_ARRAY) { @@ -392,11 +420,20 @@ GC_SET_COLOR(obj->buffered, GC_GREY); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; while (p != NULL) { pz = *(zval**)p->pData; if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { @@ -463,11 +500,20 @@ GC_SET_COLOR(obj->buffered, GC_WHITE); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return 0; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return 0; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return 0; + } + p = props->pListHead; } - p = props->pListHead; } } } @@ -506,11 +552,20 @@ GC_SET_COLOR(obj->buffered, GC_WHITE); if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; while (p != NULL) { zval_scan(*(zval**)p->pData TSRMLS_CC); p = p->pListNext; @@ -557,11 +612,20 @@ if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; } } } else { @@ -602,11 +666,20 @@ if (EXPECTED(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].valid && Z_OBJ_HANDLER_P(pz, get_properties) != NULL)) { - HashTable *props = Z_OBJPROP_P(pz); - if(!props) { - return; + if (Z_OBJCE_P(pz) == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + if (func->type != ZEND_USER_FUNCTION || !func->op_array.static_variables) { + return; + } + p = func->op_array.static_variables->pListHead; + } else { + HashTable *props = Z_OBJPROP_P(pz); + if(!props) { + return; + } + p = props->pListHead; } - p = props->pListHead; while (p != NULL) { pz = *(zval**)p->pData; if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) { Index: php5.4/Zend/zend_gc.c =================================================================== --- php5.4/Zend/zend_gc.c (revision 318599) +++ php5.4/Zend/zend_gc.c (working copy) @@ -21,6 +21,7 @@ #include "zend.h" #include "zend_API.h" +#include "zend_closures.h" #define GC_ROOT_BUFFER_MAX_ENTRIES 10000 @@ -286,7 +287,20 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + pz->refcount__gc++; + if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { + zval_scan_black(pz TSRMLS_CC); + } + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; int n = zobj->ce->default_properties_count; @@ -351,7 +365,20 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + pz->refcount__gc++; + if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) { + zval_scan_black(pz TSRMLS_CC); + } + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; for (i = 0; i < zobj->ce->default_properties_count; i++) { @@ -412,7 +439,18 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + pz->refcount__gc--; + zval_mark_grey(pz TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; int n = zobj->ce->default_properties_count; @@ -478,7 +516,18 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + pz->refcount__gc--; + zval_mark_grey(pz TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; for (i = 0; i < zobj->ce->default_properties_count; i++) { @@ -571,7 +620,17 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + zval_scan(pz TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; int n = zobj->ce->default_properties_count; @@ -638,7 +697,17 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + zval_scan(pz TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; for (i = 0; i < zobj->ce->default_properties_count; i++) { @@ -708,7 +777,19 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + zval *zv; + + zv = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (zv) { + zv->refcount__gc++; + zval_collect_white(zv TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; int n = zobj->ce->default_properties_count; @@ -787,7 +868,18 @@ if (get_props == zend_std_get_properties) { zend_object* zobj = ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(pz)].bucket.obj.object)); - if (!zobj->properties) { + if (zobj->ce == zend_ce_closure) { + const zend_function *func = zend_get_closure_method_def(pz TSRMLS_CC); + + pz = zend_get_closure_this_ptr(pz TSRMLS_CC); + if (pz) { + pz->refcount__gc++; + zval_collect_white(pz TSRMLS_CC); + } + if (func->type == ZEND_USER_FUNCTION && func->op_array.static_variables) { + p = func->op_array.static_variables->pListHead; + } + } else if (!zobj->properties) { int i; for (i = 0; i < zobj->ce->default_properties_count; i++) { |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 15:01:30 2024 UTC |