From 388c2cbdbc5a4d24a2ff52402212117348c085b4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Apr 2015 19:11:45 +0300 Subject: [PATCH] Micro optimizations --- Zend/zend_API.c | 24 +++++++++----- Zend/zend_execute.c | 10 +++--- Zend/zend_object_handlers.c | 22 ++++++++----- Zend/zend_objects.c | 18 ++++++---- Zend/zend_objects_API.c | 65 ++++++++++++++++++++++--------------- Zend/zend_opcode.c | 56 ++++++++++++++++++-------------- 6 files changed, 116 insertions(+), 79 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f028756a93..e55ec45af6 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1223,16 +1223,20 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type) /* {{{ */ { - int i; - if (class_type->default_properties_count) { - for (i = 0; i < class_type->default_properties_count; i++) { + zval *src = class_type->default_properties_table; + zval *dst = object->properties_table; + zval *end = src + class_type->default_properties_count; + + do { #if ZTS - ZVAL_DUP(&object->properties_table[i], &class_type->default_properties_table[i]); + ZVAL_DUP(dst, src); #else - ZVAL_COPY(&object->properties_table[i], &class_type->default_properties_table[i]); + ZVAL_COPY(dst, src); #endif - } + src++; + dst++; + } while (src != end); object->properties = NULL; } } @@ -3451,10 +3455,12 @@ ZEND_API int zend_fcall_info_init(zval *callable, uint check_flags, zend_fcall_i ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem) /* {{{ */ { if (fci->params) { - uint32_t i; + zval *p = fci->params; + zval *end = p + fci->param_count; - for (i = 0; i < fci->param_count; i++) { - zval_ptr_dtor(&fci->params[i]); + while (p != end) { + i_zval_ptr_dtor(p ZEND_FILE_LINE_CC); + p++; } if (free_mem) { efree(fci->params); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ffeba914e6..7d2ab9619b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2083,11 +2083,13 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data if (num_args > 0) { zval *arg_src = ZEND_CALL_ARG(call, 1); zval *arg_dst = ZEND_CALL_ARG(execute_data, 1); - uint32_t i; + zval *end = arg_src + num_args; - for (i = 0; i < num_args; i++) { - ZVAL_COPY_VALUE(arg_dst + i, arg_src + i); - } + do { + ZVAL_COPY_VALUE(arg_dst, arg_src); + arg_src++; + arg_dst++; + } while (arg_src != end); } EX(symbol_table) = NULL; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 52c3b4ce1c..b85dd840e8 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1326,16 +1326,20 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ return 1; /* different classes */ } if (!zobj1->properties && !zobj2->properties) { - int i; + zval *p1, *p2, *end; + if (!zobj1->ce->default_properties_count) { + return 0; + } + p1 = zobj1->properties_table; + p2 = zobj2->properties_table; + end = p1 + zobj1->ce->default_properties_count; Z_OBJ_PROTECT_RECURSION(o1); Z_OBJ_PROTECT_RECURSION(o2); - for (i = 0; i < zobj1->ce->default_properties_count; i++) { - if (Z_TYPE(zobj1->properties_table[i]) != IS_UNDEF) { - if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) { + do { + if (Z_TYPE_P(p1) != IS_UNDEF) { + if (Z_TYPE_P(p2) != IS_UNDEF) { zval result; - zval *p1 = &zobj1->properties_table[i]; - zval *p2 = &zobj2->properties_table[i]; if (compare_function(&result, p1, p2)==FAILURE) { Z_OBJ_UNPROTECT_RECURSION(o1); @@ -1353,13 +1357,15 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ return 1; } } else { - if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) { + if (Z_TYPE_P(p2) != IS_UNDEF) { Z_OBJ_UNPROTECT_RECURSION(o1); Z_OBJ_UNPROTECT_RECURSION(o2); return 1; } } - } + p1++; + p2++; + } while (p1 != end); Z_OBJ_UNPROTECT_RECURSION(o1); Z_OBJ_UNPROTECT_RECURSION(o2); return 0; diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 2feff81ea4..2826c322a9 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -151,14 +151,18 @@ ZEND_API zend_object *zend_objects_new(zend_class_entry *ce) ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object) { - int i; - if (old_object->ce->default_properties_count) { - for (i = 0; i < old_object->ce->default_properties_count; i++) { - zval_ptr_dtor(&new_object->properties_table[i]); - ZVAL_COPY_VALUE(&new_object->properties_table[i], &old_object->properties_table[i]); - zval_add_ref(&new_object->properties_table[i]); - } + zval *src = old_object->properties_table; + zval *dst = new_object->properties_table; + zval *end = src + old_object->ce->default_properties_count; + + do { + i_zval_ptr_dtor(dst ZEND_FILE_LINE_CC); + ZVAL_COPY_VALUE(dst, src); + zval_add_ref(dst); + src++; + dst++; + } while (src != end); } if (old_object->properties) { zval *prop, new_prop; diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 4be4723105..f48d40e5fb 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -42,46 +42,58 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects) ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects) { - uint32_t i; + if (objects->top > 1) { + zend_object **obj_ptr = objects->object_buckets + 1; + zend_object **end = objects->object_buckets + objects->top; - for (i = 1; i < objects->top ; i++) { - zend_object *obj = objects->object_buckets[i]; + do { + zend_object *obj = *obj_ptr; - if (IS_OBJ_VALID(obj)) { - if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { - GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; - GC_REFCOUNT(obj)++; - obj->handlers->dtor_obj(obj); - GC_REFCOUNT(obj)--; + if (IS_OBJ_VALID(obj)) { + if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { + GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; + GC_REFCOUNT(obj)++; + obj->handlers->dtor_obj(obj); + GC_REFCOUNT(obj)--; + } } - } + obj_ptr++; + } while (obj_ptr != end); } } ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects) { - uint32_t i; + if (objects->object_buckets && objects->top > 1) { + zend_object **obj_ptr = objects->object_buckets + 1; + zend_object **end = objects->object_buckets + objects->top; - if (!objects->object_buckets) { - return; - } - for (i = 1; i < objects->top ; i++) { - zend_object *obj = objects->object_buckets[i]; + do { + zend_object *obj = *obj_ptr; - if (IS_OBJ_VALID(obj)) { - GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; - } + if (IS_OBJ_VALID(obj)) { + GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED; + } + obj_ptr++; + } while (obj_ptr != end); } } ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects) { - uint32_t i; + zend_object **obj_ptr, **end, *obj; + + if (objects->top <= 1) { + return; + } /* Free object contents, but don't free objects themselves */ - for (i = objects->top - 1; i > 0 ; i--) { - zend_object *obj = objects->object_buckets[i]; + end = objects->object_buckets + 1; + obj_ptr = objects->object_buckets + objects->top; + do { + obj_ptr--; + obj = *obj_ptr; if (IS_OBJ_VALID(obj)) { if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED; @@ -92,20 +104,21 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects } } } - } + } while (obj_ptr != end); /* Free objects themselves if they now have a refcount of 0, which means that * they were previously part of a cycle. Everything else will report as a leak. * Cycles are allowed because not all internal objects currently support GC. */ - for (i = 1; i < objects->top ; i++) { - zend_object *obj = objects->object_buckets[i]; - + end = objects->object_buckets + objects->top; + while (obj_ptr != end) { + obj = *obj_ptr; if (IS_OBJ_VALID(obj) && GC_REFCOUNT(obj) == 0) { /* Not adding to free list as we are shutting down anyway */ void *ptr = ((char*)obj) - obj->handlers->offset; GC_REMOVE_FROM_BUFFER(obj); efree(ptr); } + obj_ptr++; } } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 98734dc533..43ba64ad3f 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -154,13 +154,15 @@ ZEND_API void zend_cleanup_user_class_data(zend_class_entry *ce) } if (ce->static_members_table) { zval *static_members = ce->static_members_table; - int count = ce->default_static_members_count; - int i; + zval *p = static_members; + zval *end = p + ce->default_static_members_count; + ce->default_static_members_count = 0; ce->default_static_members_table = ce->static_members_table = NULL; - for (i = 0; i < count; i++) { - zval_ptr_dtor(&static_members[i]); + while (p != end) { + i_zval_ptr_dtor(p ZEND_FILE_LINE_CC); + p++; } efree(static_members); } @@ -170,15 +172,17 @@ ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce) { if (CE_STATIC_MEMBERS(ce)) { zval *static_members = CE_STATIC_MEMBERS(ce); - int i; + zval *p = static_members; + zval *end = p + ce->default_static_members_count; #ifdef ZTS CG(static_members_table)[(zend_intptr_t)(ce->static_members_table)] = NULL; #else ce->static_members_table = NULL; #endif - for (i = 0; i < ce->default_static_members_count; i++) { - zval_ptr_dtor(&static_members[i]); + while (p != end) { + i_zval_ptr_dtor(p ZEND_FILE_LINE_CC); + p++; } efree(static_members); } @@ -249,22 +253,22 @@ ZEND_API void destroy_zend_class(zval *zv) switch (ce->type) { case ZEND_USER_CLASS: if (ce->default_properties_table) { - int i; + zval *p = ce->default_properties_table; + zval *end = p + ce->default_properties_count; - for (i = 0; i < ce->default_properties_count; i++) { - if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) { - zval_ptr_dtor(&ce->default_properties_table[i]); - } + while (p != end) { + i_zval_ptr_dtor(p ZEND_FILE_LINE_CC); + p++; } efree(ce->default_properties_table); } if (ce->default_static_members_table) { - int i; + zval *p = ce->default_static_members_table; + zval *end = p + ce->default_static_members_count; - for (i = 0; i < ce->default_static_members_count; i++) { - if (Z_TYPE(ce->default_static_members_table[i]) != IS_UNDEF) { - zval_ptr_dtor(&ce->default_static_members_table[i]); - } + while (p != end) { + i_zval_ptr_dtor(p ZEND_FILE_LINE_CC); + p++; } efree(ce->default_static_members_table); } @@ -292,20 +296,22 @@ ZEND_API void destroy_zend_class(zval *zv) break; case ZEND_INTERNAL_CLASS: if (ce->default_properties_table) { - int i; + zval *p = ce->default_properties_table; + zval *end = p + ce->default_properties_count; - for (i = 0; i < ce->default_properties_count; i++) { - if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) { - zval_internal_ptr_dtor(&ce->default_properties_table[i]); - } + while (p != end) { + zval_internal_ptr_dtor(p); + p++; } free(ce->default_properties_table); } if (ce->default_static_members_table) { - int i; + zval *p = ce->default_static_members_table; + zval *end = p + ce->default_static_members_count; - for (i = 0; i < ce->default_static_members_count; i++) { - zval_internal_ptr_dtor(&ce->default_static_members_table[i]); + while (p != end) { + zval_internal_ptr_dtor(p); + p++; } free(ce->default_static_members_table); } -- 2.40.0