Skip to content

Commit 9da66e6

Browse files
committed
Optimized object conversion to array without rebulding properties HashTable
1 parent f9f8c1c commit 9da66e6

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

Zend/zend_object_handlers.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,38 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
8787
}
8888
/* }}} */
8989

90+
ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj) /* {{{ */
91+
{
92+
zend_property_info *prop_info;
93+
zend_class_entry *ce = zobj->ce;
94+
HashTable *ht;
95+
zval* prop;
96+
int i;
97+
98+
ZEND_ASSERT(!zobj->properties);
99+
ht = zend_new_array(ce->default_properties_count);
100+
if (ce->default_properties_count) {
101+
zend_hash_real_init_mixed(ht);
102+
for (i = 0; i < ce->default_properties_count; i++) {
103+
prop_info = ce->properties_info_table[i];
104+
105+
if (!prop_info) {
106+
continue;
107+
}
108+
109+
prop = OBJ_PROP(zobj, prop_info->offset);
110+
if (UNEXPECTED(Z_TYPE_P(prop) == IS_UNDEF)) {
111+
continue;
112+
}
113+
114+
Z_TRY_ADDREF_P(prop);
115+
_zend_hash_append(ht, prop_info->name, prop);
116+
}
117+
}
118+
return ht;
119+
}
120+
/* }}} */
121+
90122
ZEND_API HashTable *zend_std_get_properties(zend_object *zobj) /* {{{ */
91123
{
92124
if (!zobj->properties) {

Zend/zend_object_handlers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2);
225225
ZEND_API int zend_std_get_closure(zend_object *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zend_object **obj_ptr, bool check_only);
226226
ZEND_API void rebuild_object_properties(zend_object *zobj);
227227

228+
ZEND_API HashTable *zend_std_build_object_properties_array(zend_object *zobj);
229+
228230
/* Handler for objects that cannot be meaningfully compared.
229231
* Only objects with the same identity will be considered equal. */
230232
ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2);

Zend/zend_operators.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,13 @@ ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */
713713
case IS_OBJECT:
714714
if (Z_OBJCE_P(op) == zend_ce_closure) {
715715
convert_scalar_to_array(op);
716+
} else if (Z_OBJ_P(op)->properties == NULL
717+
&& Z_OBJ_HT_P(op)->get_properties_for == NULL
718+
&& Z_OBJ_HT_P(op)->get_properties == zend_std_get_properties) {
719+
/* Optimized version without rebulding properties HashTable */
720+
HashTable *ht = zend_std_build_object_properties_array(Z_OBJ_P(op));
721+
OBJ_RELEASE(Z_OBJ_P(op));
722+
ZVAL_ARR(op, ht);
716723
} else {
717724
HashTable *obj_ht = zend_get_properties_for(op, ZEND_PROP_PURPOSE_ARRAY_CAST);
718725
if (obj_ht) {

Zend/zend_vm_def.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6139,6 +6139,11 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
61396139
} else {
61406140
ZVAL_EMPTY_ARRAY(result);
61416141
}
6142+
} else if (Z_OBJ_P(expr)->properties == NULL
6143+
&& Z_OBJ_HT_P(expr)->get_properties_for == NULL
6144+
&& Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) {
6145+
/* Optimized version without rebulding properties HashTable */
6146+
ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr)));
61426147
} else {
61436148
HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
61446149
if (obj_ht) {

Zend/zend_vm_execute.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4643,6 +4643,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
46434643
} else {
46444644
ZVAL_EMPTY_ARRAY(result);
46454645
}
4646+
} else if (Z_OBJ_P(expr)->properties == NULL
4647+
&& Z_OBJ_HT_P(expr)->get_properties_for == NULL
4648+
&& Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) {
4649+
/* Optimized version without rebulding properties HashTable */
4650+
ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr)));
46464651
} else {
46474652
HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
46484653
if (obj_ht) {
@@ -18859,6 +18864,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
1885918864
} else {
1886018865
ZVAL_EMPTY_ARRAY(result);
1886118866
}
18867+
} else if (Z_OBJ_P(expr)->properties == NULL
18868+
&& Z_OBJ_HT_P(expr)->get_properties_for == NULL
18869+
&& Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) {
18870+
/* Optimized version without rebulding properties HashTable */
18871+
ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr)));
1886218872
} else {
1886318873
HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
1886418874
if (obj_ht) {
@@ -21469,6 +21479,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
2146921479
} else {
2147021480
ZVAL_EMPTY_ARRAY(result);
2147121481
}
21482+
} else if (Z_OBJ_P(expr)->properties == NULL
21483+
&& Z_OBJ_HT_P(expr)->get_properties_for == NULL
21484+
&& Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) {
21485+
/* Optimized version without rebulding properties HashTable */
21486+
ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr)));
2147221487
} else {
2147321488
HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
2147421489
if (obj_ht) {
@@ -38144,6 +38159,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
3814438159
} else {
3814538160
ZVAL_EMPTY_ARRAY(result);
3814638161
}
38162+
} else if (Z_OBJ_P(expr)->properties == NULL
38163+
&& Z_OBJ_HT_P(expr)->get_properties_for == NULL
38164+
&& Z_OBJ_HT_P(expr)->get_properties == zend_std_get_properties) {
38165+
/* Optimized version without rebulding properties HashTable */
38166+
ZVAL_ARR(result, zend_std_build_object_properties_array(Z_OBJ_P(expr)));
3814738167
} else {
3814838168
HashTable *obj_ht = zend_get_properties_for(expr, ZEND_PROP_PURPOSE_ARRAY_CAST);
3814938169
if (obj_ht) {

0 commit comments

Comments
 (0)