diff options
Diffstat (limited to 'ext/spl/spl_fixedarray.c')
-rw-r--r-- | ext/spl/spl_fixedarray.c | 103 |
1 files changed, 52 insertions, 51 deletions
diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 4b0d186a78..d3726b4c3f 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -41,17 +41,22 @@ ZEND_GET_MODULE(spl_fixedarray) typedef struct _spl_fixedarray { zend_long size; + /* It is possible to resize this, so this can't be combined with the object */ zval *elements; } spl_fixedarray; -typedef struct _spl_fixedarray_object { - spl_fixedarray array; +typedef struct _spl_fixedarray_methods { zend_function *fptr_offset_get; zend_function *fptr_offset_set; zend_function *fptr_offset_has; zend_function *fptr_offset_del; zend_function *fptr_count; - zend_object std; +} spl_fixedarray_methods; + +typedef struct _spl_fixedarray_object { + spl_fixedarray array; + spl_fixedarray_methods *methods; + zend_object std; } spl_fixedarray_object; typedef struct _spl_fixedarray_it { @@ -222,6 +227,9 @@ static void spl_fixedarray_object_free_storage(zend_object *object) spl_fixedarray_object *intern = spl_fixed_array_from_obj(object); spl_fixedarray_dtor(&intern->array); zend_object_std_dtor(&intern->std); + if (intern->methods) { + efree(intern->methods); + } } static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, zend_object *orig, bool clone_orig) @@ -252,26 +260,34 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z ZEND_ASSERT(parent); - if (inherited) { - intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); - if (intern->fptr_offset_get->common.scope == parent) { - intern->fptr_offset_get = NULL; + if (UNEXPECTED(inherited)) { + spl_fixedarray_methods methods; + methods.fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); + if (methods.fptr_offset_get->common.scope == parent) { + methods.fptr_offset_get = NULL; } - intern->fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1); - if (intern->fptr_offset_set->common.scope == parent) { - intern->fptr_offset_set = NULL; + methods.fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1); + if (methods.fptr_offset_set->common.scope == parent) { + methods.fptr_offset_set = NULL; } - intern->fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1); - if (intern->fptr_offset_has->common.scope == parent) { - intern->fptr_offset_has = NULL; + methods.fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1); + if (methods.fptr_offset_has->common.scope == parent) { + methods.fptr_offset_has = NULL; } - intern->fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1); - if (intern->fptr_offset_del->common.scope == parent) { - intern->fptr_offset_del = NULL; + methods.fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1); + if (methods.fptr_offset_del->common.scope == parent) { + methods.fptr_offset_del = NULL; } - intern->fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1); - if (intern->fptr_count->common.scope == parent) { - intern->fptr_count = NULL; + methods.fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1); + if (methods.fptr_count->common.scope == parent) { + methods.fptr_count = NULL; + } + /* Assume that most of the time in performance-sensitive code, SplFixedArray won't be subclassed with overrides for these ArrayAccess methods. */ + /* Save 32 bytes per object on 64-bit systems by combining the 5 null pointers into 1 null pointer */ + /* (This is already looking up 5 functions when any subclass of SplFixedArray is instantiated, which is inefficient) */ + if (methods.fptr_offset_get || methods.fptr_offset_set || methods.fptr_offset_del || methods.fptr_offset_has || methods.fptr_count) { + intern->methods = emalloc(sizeof(spl_fixedarray_methods)); + *intern->methods = methods; } } @@ -329,16 +345,13 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off return &EG(uninitialized_zval); } - if (intern->fptr_offset_get) { + if (UNEXPECTED(intern->methods && intern->methods->fptr_offset_get)) { zval tmp; if (!offset) { ZVAL_NULL(&tmp); offset = &tmp; - } else { - SEPARATE_ARG_IF_REF(offset); } - zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", rv, offset); - zval_ptr_dtor(offset); + zend_call_method_with_1_params(object, intern->std.ce, &intern->methods->fptr_offset_get, "offsetGet", rv, offset); if (!Z_ISUNDEF_P(rv)) { return rv; } @@ -380,17 +393,12 @@ static void spl_fixedarray_object_write_dimension(zend_object *object, zval *off intern = spl_fixed_array_from_obj(object); - if (intern->fptr_offset_set) { + if (UNEXPECTED(intern->methods && intern->methods->fptr_offset_set)) { if (!offset) { ZVAL_NULL(&tmp); offset = &tmp; - } else { - SEPARATE_ARG_IF_REF(offset); } - SEPARATE_ARG_IF_REF(value); - zend_call_method_with_2_params(object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value); - zval_ptr_dtor(value); - zval_ptr_dtor(offset); + zend_call_method_with_2_params(object, intern->std.ce, &intern->methods->fptr_offset_set, "offsetSet", NULL, offset, value); return; } @@ -422,10 +430,8 @@ static void spl_fixedarray_object_unset_dimension(zend_object *object, zval *off intern = spl_fixed_array_from_obj(object); - if (intern->fptr_offset_del) { - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset); - zval_ptr_dtor(offset); + if (UNEXPECTED(intern->methods && intern->methods->fptr_offset_del)) { + zend_call_method_with_1_params(object, intern->std.ce, &intern->methods->fptr_offset_del, "offsetUnset", NULL, offset); return; } @@ -462,13 +468,11 @@ static int spl_fixedarray_object_has_dimension(zend_object *object, zval *offset intern = spl_fixed_array_from_obj(object); - if (intern->fptr_offset_has) { + if (UNEXPECTED(intern->methods && intern->methods->fptr_offset_has)) { zval rv; - zend_bool result; + bool result; - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_has, "offsetExists", &rv, offset); - zval_ptr_dtor(offset); + zend_call_method_with_1_params(object, intern->std.ce, &intern->methods->fptr_offset_has, "offsetExists", &rv, offset); result = zend_is_true(&rv); zval_ptr_dtor(&rv); return result; @@ -482,9 +486,9 @@ static int spl_fixedarray_object_count_elements(zend_object *object, zend_long * spl_fixedarray_object *intern; intern = spl_fixed_array_from_obj(object); - if (intern->fptr_count) { + if (UNEXPECTED(intern->methods && intern->methods->fptr_count)) { zval rv; - zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv); + zend_call_method_with_0_params(object, intern->std.ce, &intern->methods->fptr_count, "count", &rv); if (!Z_ISUNDEF(rv)) { *count = zval_get_long(&rv); zval_ptr_dtor(&rv); @@ -589,7 +593,7 @@ PHP_METHOD(SplFixedArray, fromArray) spl_fixedarray array; spl_fixedarray_object *intern; int num; - zend_bool save_indexes = 1; + bool save_indexes = 1; if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|b", &data, &save_indexes) == FAILURE) { RETURN_THROWS(); @@ -834,7 +838,11 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob PHP_MINIT_FUNCTION(spl_fixedarray) { - REGISTER_SPL_STD_CLASS_EX(SplFixedArray, spl_fixedarray_new, class_SplFixedArray_methods); + spl_ce_SplFixedArray = register_class_SplFixedArray(zend_ce_aggregate, zend_ce_arrayaccess, zend_ce_countable); + spl_ce_SplFixedArray->create_object = spl_fixedarray_new; + spl_ce_SplFixedArray->get_iterator = spl_fixedarray_get_iterator; + spl_ce_SplFixedArray->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR; + memcpy(&spl_handler_SplFixedArray, &std_object_handlers, sizeof(zend_object_handlers)); spl_handler_SplFixedArray.offset = XtOffsetOf(spl_fixedarray_object, std); @@ -849,12 +857,5 @@ PHP_MINIT_FUNCTION(spl_fixedarray) spl_handler_SplFixedArray.dtor_obj = zend_objects_destroy_object; spl_handler_SplFixedArray.free_obj = spl_fixedarray_object_free_storage; - REGISTER_SPL_IMPLEMENTS(SplFixedArray, Aggregate); - REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess); - REGISTER_SPL_IMPLEMENTS(SplFixedArray, Countable); - - spl_ce_SplFixedArray->get_iterator = spl_fixedarray_get_iterator; - spl_ce_SplFixedArray->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR; - return SUCCESS; } |