summaryrefslogtreecommitdiff
path: root/ext/spl/spl_fixedarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/spl_fixedarray.c')
-rw-r--r--ext/spl/spl_fixedarray.c103
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;
}