Skip to content

[Proposal] Reduce the minimum size for packed arrays from 8 to 2 #4783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3299,7 +3299,7 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
if (zend_is_callable_ex(callable, NULL, 0, callable_name, &fcc, NULL)) {
if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
zval_ptr_dtor_str(callable);
array_init(callable);
array_init_size(callable, 2);
add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name));
add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name));
}
Expand Down
6 changes: 4 additions & 2 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,10 @@ ZEND_API const char *zend_get_type_by_const(int type);
#define DLEXPORT
#endif

#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
#define array_init(arg) ZVAL_ARR((arg), zend_new_array(0))
#define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size))
#define array_init_assoc(arg) ZVAL_ARR((arg), zend_new_array_assoc(0))
#define array_init_assoc_size(arg, size) ZVAL_ARR((arg), zend_new_array_assoc(size))
Comment on lines -419 to +422
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HashTable may be in 3 states - packed, map and uninitialized. array_init() creates HashTable in unitilaized state and it may become packed or map depending on the following zend_hash_real_init_* or update operations.

array_init_assoc() creates HashTable in unitilaized state as well, despite of the name.

ZEND_API int object_init(zval *arg);
ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties);
Expand Down
8 changes: 5 additions & 3 deletions Zend/zend_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,13 +692,15 @@ ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_c
{
uint32_t i;
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t n_children = list->children;

if (!list->children) {
if (!n_children) {
ZVAL_EMPTY_ARRAY(result);
break;
}
array_init(result);
for (i = 0; i < list->children; i++) {
/** Usually, there won't be an AST_UNPACK or duplicate keys. Assume that's the initial capacity. */
array_init_size(result, n_children);
for (i = 0; i < n_children; i++) {
zend_ast *elem = list->child[i];
if (elem->kind == ZEND_AST_UNPACK) {
if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[0], scope) != SUCCESS)) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ ZEND_FUNCTION(gc_status)

zend_gc_get_status(&status);

array_init_size(return_value, 3);
array_init_assoc_size(return_value, 4);

add_assoc_long_ex(return_value, "runs", sizeof("runs")-1, (long)status.runs);
add_assoc_long_ex(return_value, "collected", sizeof("collected")-1, (long)status.collected);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -2165,7 +2165,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *
return;
}
}
array_init(container);
array_init(container); /* TODO benchmark and check if array_init_assoc is faster */
goto fetch_from_array;
} else {
goto return_null;
Expand Down
50 changes: 41 additions & 9 deletions Zend/zend_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,18 @@ static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht)
uint32_t nSize = ht->nTableSize;

if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) {
if (nSize < HT_MIN_SIZE_UNPACKED) {
nSize = HT_MIN_SIZE_UNPACKED;
ht->nTableSize = HT_MIN_SIZE_UNPACKED;
}
data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), 1);
} else if (EXPECTED(nSize == HT_MIN_SIZE)) {
data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE)));
ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE);
} else if (EXPECTED(nSize <= HT_MIN_SIZE_UNPACKED)) {
if (nSize < HT_MIN_SIZE_UNPACKED) {
nSize = HT_MIN_SIZE_UNPACKED;
ht->nTableSize = HT_MIN_SIZE_UNPACKED;
}
data = emalloc(HT_SIZE_EX(HT_MIN_SIZE_UNPACKED, HT_SIZE_TO_MASK(HT_MIN_SIZE_UNPACKED)));
ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE_UNPACKED);
HT_SET_DATA_ADDR(ht, data);
/* Don't overwrite iterator count. */
ht->u.v.flags = HASH_FLAG_STATIC_KEYS;
Expand Down Expand Up @@ -232,6 +240,7 @@ static zend_always_inline void zend_hash_real_init_ex(HashTable *ht, int packed)
static const uint32_t uninitialized_bucket[-HT_MIN_MASK] =
{HT_INVALID_IDX, HT_INVALID_IDX};

/* XXX: Is MIN_SIZE_UNPACKED the best choice vs this (8 vs 2)? Haven't benchmarked it. */
ZEND_API const HashTable zend_empty_array = {
.gc.refcount = 2,
.gc.u.type_info = IS_ARRAY | (GC_IMMUTABLE << GC_FLAGS_SHIFT),
Expand All @@ -240,7 +249,7 @@ ZEND_API const HashTable zend_empty_array = {
.arData = (Bucket*)&uninitialized_bucket[2],
.nNumUsed = 0,
.nNumOfElements = 0,
.nTableSize = HT_MIN_SIZE,
.nTableSize = HT_MIN_SIZE_UNPACKED,
.nInternalPointer = 0,
.nNextFreeElement = 0,
.pDestructor = ZVAL_PTR_DTOR
Expand All @@ -258,7 +267,8 @@ static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize
ht->nInternalPointer = 0;
ht->nNextFreeElement = ZEND_LONG_MIN;
ht->pDestructor = pDestructor;
ht->nTableSize = zend_hash_check_size(nSize);
/* TODO: Decide on the best way to specify the size of a packed table exactly? This is a first attempt*/
ht->nTableSize = (nSize <= HT_MIN_SIZE_UNPACKED ? (nSize < HT_MIN_SIZE ? HT_MIN_SIZE : nSize) : zend_hash_check_size(nSize));
}

ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
Expand All @@ -273,17 +283,32 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void)
return ht;
}

ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_assoc_0(void)
{
HashTable *ht = emalloc(sizeof(HashTable));
_zend_hash_init_int(ht, HT_MIN_SIZE_UNPACKED, ZVAL_PTR_DTOR, 0);
return ht;
}

ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize)
{
HashTable *ht = emalloc(sizeof(HashTable));
_zend_hash_init_int(ht, nSize, ZVAL_PTR_DTOR, 0);
return ht;
}

ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_assoc(uint32_t nSize)
{
HashTable *ht = emalloc(sizeof(HashTable));
_zend_hash_init_int(ht, nSize < HT_MIN_SIZE_UNPACKED ? HT_MIN_SIZE_UNPACKED : nSize, ZVAL_PTR_DTOR, 0);
return ht;
}

ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2)
{
Bucket *p;
HashTable *ht = emalloc(sizeof(HashTable));
/* XXX: Currently, HT_MIN_SIZE == 2. will need to adjust all calls like this if HT_MIN_SIZE goes below 2 */
_zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, 0);
ht->nNumUsed = ht->nNumOfElements = ht->nNextFreeElement = 2;
zend_hash_real_init_packed_ex(ht);
Expand Down Expand Up @@ -339,11 +364,18 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht)
void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
Bucket *old_buckets = ht->arData;
uint32_t nSize = ht->nTableSize;
if (nSize < HT_MIN_SIZE_UNPACKED) {
nSize = HT_MIN_SIZE_UNPACKED;
ht->nTableSize = HT_MIN_SIZE_UNPACKED;
} else if (nSize & (nSize - 1)) {
nSize = zend_hash_check_size(nSize);
ht->nTableSize = nSize;
}

HT_ASSERT_RC1(ht);
HT_FLAGS(ht) &= ~HASH_FLAG_PACKED;
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
ht->nTableMask = HT_SIZE_TO_MASK(nSize);
HT_SET_DATA_ADDR(ht, new_data);
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
Expand Down Expand Up @@ -1177,14 +1209,14 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)

if (ht->nNumUsed > ht->nNumOfElements + (ht->nNumOfElements >> 5)) { /* additional term is there to amortize the cost of compaction */
zend_hash_rehash(ht);
} else if (ht->nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
} else if (EXPECTED(ht->nTableSize < HT_MAX_SIZE)) { /* Let's double the table size */
void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
uint32_t nSize = ht->nTableSize + ht->nTableSize;
uint32_t nSize = zend_hash_check_size(ht->nTableSize + ht->nTableSize);
Bucket *old_buckets = ht->arData;

ht->nTableSize = nSize;
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
ht->nTableMask = HT_SIZE_TO_MASK(nSize);
HT_SET_DATA_ADDR(ht, new_data);
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
Expand Down
14 changes: 14 additions & 0 deletions Zend/zend_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -292,13 +292,27 @@ ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
: \
_zend_new_array((size)) \
)
# define zend_new_array_assoc(size) \
(__builtin_constant_p(size) ? \
((((uint32_t)(size)) <= HT_MIN_SIZE_UNPACKED) ? \
_zend_new_array_assoc_0() \
: \
_zend_new_array_assoc((size)) \
) \
: \
_zend_new_array_assoc((size)) \
)
#else
# define zend_new_array(size) \
_zend_new_array(size)
# define zend_new_array_assoc(size) \
_zend_new_array_assoc(size)
#endif

ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void);
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_assoc_0(void);
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size);
ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_assoc(uint32_t size);
ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2);
ZEND_API uint32_t zend_array_count(HashTable *ht);
ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */
} else {
zval_ptr_dtor(op);
/*ZVAL_EMPTY_ARRAY(op);*/
array_init(op);
array_init_assoc(op);
}
}
break;
Expand Down
15 changes: 12 additions & 3 deletions Zend/zend_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,8 @@ struct _zend_array {
#define HT_INVALID_IDX ((uint32_t) -1)

#define HT_MIN_MASK ((uint32_t) -2)
#define HT_MIN_SIZE 8
#define HT_MIN_SIZE 2
#define HT_MIN_SIZE_UNPACKED 8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UNPACKED is a bad name. We already use HASH_MAP name it iterators API.
Also the meaning of HT_MIN_SIZE is not clear now. Should it be renamed into HT_MIN_SIZE_PACKED?


#if SIZEOF_SIZE_T == 4
# define HT_MAX_SIZE 0x04000000 /* small enough to avoid overflow checks */
Expand Down Expand Up @@ -422,7 +423,7 @@ struct _zend_array {
HT_HASH_EX((ht)->arData, idx)

#define HT_SIZE_TO_MASK(nTableSize) \
((uint32_t)(-((nTableSize) + (nTableSize))))
(uint32_t)(-(zend_hash_check_size((nTableSize) + (nTableSize))))
#define HT_HASH_SIZE(nTableMask) \
(((size_t)(uint32_t)-(int32_t)(nTableMask)) * sizeof(uint32_t))
#define HT_DATA_SIZE(nTableSize) \
Expand All @@ -439,7 +440,15 @@ struct _zend_array {
size_t size = HT_HASH_SIZE((ht)->nTableMask); \
__m128i xmm0 = _mm_setzero_si128(); \
xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \
ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \
if (size < 64) { \
ZEND_ASSERT(size == 16 || size == 32); \
_mm_storeu_si128((__m128i*)p, xmm0); \
if (size >= 32) { \
_mm_storeu_si128((__m128i*)(p+16), xmm0); \
} \
break; \
} \
Comment on lines +443 to +450
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How this is related to packed array size? This code is for assoc/maps only.

ZEND_ASSERT(((size & 0x3f) == 0)); \
do { \
_mm_storeu_si128((__m128i*)p, xmm0); \
_mm_storeu_si128((__m128i*)(p+16), xmm0); \
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -5801,7 +5801,7 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
}
Z_OBJ_P(result)->properties = ht;
} else if (Z_TYPE_P(expr) != IS_NULL) {
Z_OBJ_P(result)->properties = ht = zend_new_array(1);
Z_OBJ_P(result)->properties = ht = zend_new_array_assoc(1);
expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
if (OP1_TYPE == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
Expand Down
8 changes: 4 additions & 4 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -3966,7 +3966,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
}
Z_OBJ_P(result)->properties = ht;
} else if (Z_TYPE_P(expr) != IS_NULL) {
Z_OBJ_P(result)->properties = ht = zend_new_array(1);
Z_OBJ_P(result)->properties = ht = zend_new_array_assoc(1);
expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
if (IS_CONST == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
Expand Down Expand Up @@ -17626,7 +17626,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
}
Z_OBJ_P(result)->properties = ht;
} else if (Z_TYPE_P(expr) != IS_NULL) {
Z_OBJ_P(result)->properties = ht = zend_new_array(1);
Z_OBJ_P(result)->properties = ht = zend_new_array_assoc(1);
expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
if (IS_TMP_VAR == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
Expand Down Expand Up @@ -20284,7 +20284,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
}
Z_OBJ_P(result)->properties = ht;
} else if (Z_TYPE_P(expr) != IS_NULL) {
Z_OBJ_P(result)->properties = ht = zend_new_array(1);
Z_OBJ_P(result)->properties = ht = zend_new_array_assoc(1);
expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
if (IS_VAR == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
Expand Down Expand Up @@ -36211,7 +36211,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
}
Z_OBJ_P(result)->properties = ht;
} else if (Z_TYPE_P(expr) != IS_NULL) {
Z_OBJ_P(result)->properties = ht = zend_new_array(1);
Z_OBJ_P(result)->properties = ht = zend_new_array_assoc(1);
expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
if (IS_CV == IS_CONST) {
if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
Expand Down
2 changes: 1 addition & 1 deletion ext/json/json_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ static int php_json_parser_array_append(php_json_parser *parser, zval *array, zv
static int php_json_parser_object_create(php_json_parser *parser, zval *object)
{
if (parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) {
array_init(object);
array_init_assoc(object);
return SUCCESS;
} else {
return object_init(object);
Expand Down
3 changes: 2 additions & 1 deletion ext/opcache/zend_persist.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ static void zend_hash_persist(HashTable *ht)
void *data = HT_GET_DATA_ADDR(ht);
data = zend_shared_memdup_free(data, HT_USED_SIZE(ht));
HT_SET_DATA_ADDR(ht, data);
} else if (ht->nNumUsed > HT_MIN_SIZE && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) {
} else if (ht->nNumUsed > HT_MIN_SIZE_UNPACKED && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) {
/* TODO any special considerations for this? */
/* compact table */
void *old_data = HT_GET_DATA_ADDR(ht);
Bucket *old_buckets = ht->arData;
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/zend_persist_calc.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static void zend_hash_persist_calc(HashTable *ht)
return;
}

if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED) && ht->nNumUsed > HT_MIN_SIZE && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) {
if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED) && ht->nNumUsed > HT_MIN_SIZE_UNPACKED && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) {
/* compact table */
uint32_t hash_size;

Expand Down
6 changes: 3 additions & 3 deletions ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2633,9 +2633,9 @@ PHP_FUNCTION(compact)
or multiple string names, rather than a combination of both.
So quickly guess a minimum result size based on that */
if (num_args && Z_TYPE(args[0]) == IS_ARRAY) {
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL(args[0])));
array_init_assoc_size(return_value, zend_hash_num_elements(Z_ARRVAL(args[0])));
} else {
array_init_size(return_value, num_args);
array_init_assoc_size(return_value, num_args);
}

for (i = 0; i < num_args; i++) {
Expand Down Expand Up @@ -2726,7 +2726,7 @@ PHP_FUNCTION(array_fill_keys)
ZEND_PARSE_PARAMETERS_END();

/* Initialize return array */
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(keys)));
array_init_assoc_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(keys)));

ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) {
ZVAL_DEREF(entry);
Expand Down
4 changes: 2 additions & 2 deletions ext/standard/basic_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,7 +1287,7 @@ PHP_FUNCTION(time_nanosleep)
if (!nanosleep(&php_req, &php_rem)) {
RETURN_TRUE;
} else if (errno == EINTR) {
array_init(return_value);
array_init_size(return_value, 2);
add_assoc_long_ex(return_value, "seconds", sizeof("seconds")-1, php_rem.tv_sec);
add_assoc_long_ex(return_value, "nanoseconds", sizeof("nanoseconds")-1, php_rem.tv_nsec);
return;
Expand Down Expand Up @@ -1528,7 +1528,7 @@ PHP_FUNCTION(error_get_last)
ZEND_PARSE_PARAMETERS_NONE();

if (PG(last_error_message)) {
array_init(return_value);
array_init_size(return_value, 4);
add_assoc_long_ex(return_value, "type", sizeof("type")-1, PG(last_error_type));
add_assoc_str_ex(return_value, "message", sizeof("message")-1,
zend_string_copy(PG(last_error_message)));
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ PHP_FUNCTION(strptime)
RETURN_FALSE;
}

array_init(return_value);
array_init_size(return_value, 9);
add_assoc_long(return_value, "tm_sec", parsed_time.tm_sec);
add_assoc_long(return_value, "tm_min", parsed_time.tm_min);
add_assoc_long(return_value, "tm_hour", parsed_time.tm_hour);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ PHP_FUNCTION(scandir)
RETURN_FALSE;
}

array_init(return_value);
array_init_size(return_value, n);

for (i = 0; i < n; i++) {
add_next_index_str(return_value, namelist[i]);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ PHP_FUNCTION(fstat)
RETURN_FALSE;
}

array_init(return_value);
array_init_size(return_value, 26);

ZVAL_LONG(&stat_dev, stat_ssb.sb.st_dev);
ZVAL_LONG(&stat_ino, stat_ssb.sb.st_ino);
Expand Down
2 changes: 1 addition & 1 deletion ext/standard/scanf.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format,
zval tmp;

/* allocate an array for return */
array_init(return_value);
array_init_size(return_value, totalVars);

for (i = 0; i < totalVars; i++) {
ZVAL_NULL(&tmp);
Expand Down
Loading