]> granicus.if.org Git - php/commitdiff
Optimize zend_mm_small_size_to_bin()
authorBob Weinand <bobwei9@hotmail.com>
Sat, 19 Sep 2015 21:07:43 +0000 (23:07 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Sat, 19 Sep 2015 21:07:43 +0000 (23:07 +0200)
It removes a cmov operation and has a much faster branch for small allocations (especially when handling strings) (<= 64 bytes)

Zend/zend_alloc.c
Zend/zend_closures.c
Zend/zend_execute.c

index bf147f55e543c364678feecf428bc730f3f56021..bd3fe0ebcccb48c23d89bb7d9d5f8d01cda48034 100644 (file)
@@ -1202,17 +1202,19 @@ static zend_always_inline int zend_mm_small_size_to_bin(size_t size)
        n = zend_mm_small_size_to_bit(size - 1);
        return ((size-1) >> f1[n]) + f2[n];
 #else
-       int t1, t2, t3;
-
-       if (UNEXPECTED(size <= 8)) return 0;
-       t1 = (int)(size - 1);
-       t2 = zend_mm_small_size_to_bit(t1);
-       t3 = t2 - 6;
-       t3 = (t3 < 0) ? 0 : t3;
-       t2 = t3 + 3;
-       t1 = t1 >> t2;
-       t3 = t3 << 2;
-       return t1 + t3;
+       unsigned int t1, t2;
+
+       if (size <= 64) {
+               /* we need to support size == 0 ... */
+               return (size - !!size) >> 3;
+       } else {
+               t1 = size - 1;
+               t2 = zend_mm_small_size_to_bit(t1) - 3;
+               t1 = t1 >> t2;
+               t2 = t2 - 3;
+               t2 = t2 << 2;
+               return (int)(t1 + t2);
+       }
 #endif
 }
 
index 50aa7d4188c12c46d336174079396cfd5894f2ab..251710e326ae411c7f2bc14247226bd8954bb6b6 100644 (file)
@@ -134,7 +134,7 @@ ZEND_METHOD(Closure, call)
                fci_cache.function_handler = &my_function;
 
                /* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */
-               if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) {
+               if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis) && my_function.op_array.cache_size) {
                        my_function.op_array.run_time_cache = emalloc(my_function.op_array.cache_size);
                        memset(my_function.op_array.run_time_cache, 0, my_function.op_array.cache_size);
                }
@@ -206,7 +206,7 @@ ZEND_METHOD(Closure, bind)
        new_closure = (zend_closure *) Z_OBJ_P(return_value);
 
        /* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */
-       if (ZEND_USER_CODE(closure->func.type) && (closure->func.common.scope != new_closure->func.common.scope || (closure->func.op_array.fn_flags & ZEND_ACC_NO_RT_ARENA))) {
+       if (ZEND_USER_CODE(closure->func.type) && (closure->func.common.scope != new_closure->func.common.scope || (closure->func.op_array.fn_flags & ZEND_ACC_NO_RT_ARENA)) && new_closure->func.op_array.cache_size) {
                new_closure->func.op_array.run_time_cache = emalloc(new_closure->func.op_array.cache_size);
                memset(new_closure->func.op_array.run_time_cache, 0, new_closure->func.op_array.cache_size);
 
@@ -543,7 +543,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
                        zend_hash_init(closure->func.op_array.static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0);
                        zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables);
                }
-               if (UNEXPECTED(!closure->func.op_array.run_time_cache)) {
+               if (UNEXPECTED(!closure->func.op_array.run_time_cache) && func->op_array.cache_size) {
                        closure->func.op_array.run_time_cache = func->op_array.run_time_cache = zend_arena_alloc(&CG(arena), func->op_array.cache_size);
                        memset(func->op_array.run_time_cache, 0, func->op_array.cache_size);
                }
index 67a6bc2d2793c4d6f448bcd58e0cde47139428c4..dcf2d4a7ce8c44654ae412b245487ec9177bb833 100644 (file)
@@ -2166,7 +2166,7 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
                GC_REFCOUNT(Z_OBJ(EX(This)))++;
        }
 
-       if (UNEXPECTED(!op_array->run_time_cache)) {
+       if (UNEXPECTED(!op_array->run_time_cache) && op_array->cache_size) {
                op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
                memset(op_array->run_time_cache, 0, op_array->cache_size);
        }
@@ -2193,7 +2193,7 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
                GC_REFCOUNT(Z_OBJ(EX(This)))++;
        }
 
-       if (!op_array->run_time_cache) {
+       if (!op_array->run_time_cache && op_array->cache_size) {
                op_array->run_time_cache = emalloc(op_array->cache_size);
                memset(op_array->run_time_cache, 0, op_array->cache_size);
        }