]> granicus.if.org Git - php/commitdiff
Optimize object to array casting
authorDmitry Stogov <dmitry@zend.com>
Thu, 5 Jul 2018 22:25:24 +0000 (01:25 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 5 Jul 2018 22:25:24 +0000 (01:25 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 5fb94b142ec988600866fb12fa95ed3c677354c3..4db0e7beba0706ea849928b0abdf0b5217db7e07 100644 (file)
@@ -5270,6 +5270,7 @@ ZEND_VM_COLD_CONST_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
        zend_free_op free_op1;
        zval *expr;
        zval *result = EX_VAR(opline->result.var);
+       HashTable *ht;
 
        SAVE_OPLINE();
        expr = GET_OP1_ZVAL_PTR(BP_VAR_R);
@@ -5310,7 +5311,7 @@ ZEND_VM_COLD_CONST_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
                                        if (Z_TYPE_P(expr) != IS_NULL) {
-                                               ZVAL_ARR(result, zend_new_array(8));
+                                               ZVAL_ARR(result, zend_new_array(1));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (OP1_TYPE == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
@@ -5326,19 +5327,22 @@ ZEND_VM_COLD_CONST_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
                                        convert_to_array(result);
                                }
                        } else {
-                               if (Z_TYPE_P(expr) != IS_ARRAY) {
-                                       object_init(result);
-                                       if (Z_TYPE_P(expr) != IS_NULL) {
-                                               expr = zend_hash_add_new(Z_OBJPROP_P(result), ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
-                                               if (OP1_TYPE == IS_CONST) {
-                                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
-                                               } else {
-                                                       if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
-                                               }
+                               ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
+                               if (Z_TYPE_P(expr) == IS_ARRAY) {
+                                       ht = zend_symtable_to_proptable(Z_ARR_P(expr));
+                                       if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
+                                               /* TODO: try not to duplicate immutable arrays as well ??? */
+                                               ht = zend_array_dup(ht);
+                                       }
+                                       Z_OBJ_P(result)->properties = ht;
+                               } else if (Z_TYPE_P(expr) != IS_NULL) {
+                                       Z_OBJ_P(result)->properties = ht = zend_new_array(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);
+                                       } else {
+                                               if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                        }
-                               } else {
-                                       ZVAL_COPY(result, expr);
-                                       convert_to_object(result);
                                }
                        }
        }
index 7aeb0a7d39cf389d7b03d7c460498bac00f06f44..f1cd5c17d77d9dfac527bafb80f1ae095d76632a 100644 (file)
@@ -3213,6 +3213,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
 
        zval *expr;
        zval *result = EX_VAR(opline->result.var);
+       HashTable *ht;
 
        SAVE_OPLINE();
        expr = RT_CONSTANT(opline, opline->op1);
@@ -3252,7 +3253,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
                                        if (Z_TYPE_P(expr) != IS_NULL) {
-                                               ZVAL_ARR(result, zend_new_array(8));
+                                               ZVAL_ARR(result, zend_new_array(1));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_CONST == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
@@ -3268,19 +3269,22 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CONST_H
                                        convert_to_array(result);
                                }
                        } else {
-                               if (Z_TYPE_P(expr) != IS_ARRAY) {
-                                       object_init(result);
-                                       if (Z_TYPE_P(expr) != IS_NULL) {
-                                               expr = zend_hash_add_new(Z_OBJPROP_P(result), ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
-                                               if (IS_CONST == IS_CONST) {
-                                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
-                                               } else {
-                                                       if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
-                                               }
+                               ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
+                               if (Z_TYPE_P(expr) == IS_ARRAY) {
+                                       ht = zend_symtable_to_proptable(Z_ARR_P(expr));
+                                       if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
+                                               /* TODO: try not to duplicate immutable arrays as well ??? */
+                                               ht = zend_array_dup(ht);
+                                       }
+                                       Z_OBJ_P(result)->properties = ht;
+                               } else if (Z_TYPE_P(expr) != IS_NULL) {
+                                       Z_OBJ_P(result)->properties = ht = zend_new_array(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);
+                                       } else {
+                                               if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                        }
-                               } else {
-                                       ZVAL_COPY(result, expr);
-                                       convert_to_object(result);
                                }
                        }
        }
@@ -18033,6 +18037,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
        zend_free_op free_op1;
        zval *expr;
        zval *result = EX_VAR(opline->result.var);
+       HashTable *ht;
 
        SAVE_OPLINE();
        expr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@@ -18072,7 +18077,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
                                        if (Z_TYPE_P(expr) != IS_NULL) {
-                                               ZVAL_ARR(result, zend_new_array(8));
+                                               ZVAL_ARR(result, zend_new_array(1));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_TMP_VAR == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
@@ -18088,19 +18093,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPC
                                        convert_to_array(result);
                                }
                        } else {
-                               if (Z_TYPE_P(expr) != IS_ARRAY) {
-                                       object_init(result);
-                                       if (Z_TYPE_P(expr) != IS_NULL) {
-                                               expr = zend_hash_add_new(Z_OBJPROP_P(result), ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
-                                               if (IS_TMP_VAR == IS_CONST) {
-                                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
-                                               } else {
-                                                       if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
-                                               }
+                               ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
+                               if (Z_TYPE_P(expr) == IS_ARRAY) {
+                                       ht = zend_symtable_to_proptable(Z_ARR_P(expr));
+                                       if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
+                                               /* TODO: try not to duplicate immutable arrays as well ??? */
+                                               ht = zend_array_dup(ht);
+                                       }
+                                       Z_OBJ_P(result)->properties = ht;
+                               } else if (Z_TYPE_P(expr) != IS_NULL) {
+                                       Z_OBJ_P(result)->properties = ht = zend_new_array(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);
+                                       } else {
+                                               if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                        }
-                               } else {
-                                       ZVAL_COPY(result, expr);
-                                       convert_to_object(result);
                                }
                        }
        }
@@ -21071,6 +21079,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
        zend_free_op free_op1;
        zval *expr;
        zval *result = EX_VAR(opline->result.var);
+       HashTable *ht;
 
        SAVE_OPLINE();
        expr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@@ -21111,7 +21120,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
                                        if (Z_TYPE_P(expr) != IS_NULL) {
-                                               ZVAL_ARR(result, zend_new_array(8));
+                                               ZVAL_ARR(result, zend_new_array(1));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_VAR == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
@@ -21127,19 +21136,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPC
                                        convert_to_array(result);
                                }
                        } else {
-                               if (Z_TYPE_P(expr) != IS_ARRAY) {
-                                       object_init(result);
-                                       if (Z_TYPE_P(expr) != IS_NULL) {
-                                               expr = zend_hash_add_new(Z_OBJPROP_P(result), ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
-                                               if (IS_VAR == IS_CONST) {
-                                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
-                                               } else {
-                                                       if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
-                                               }
+                               ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
+                               if (Z_TYPE_P(expr) == IS_ARRAY) {
+                                       ht = zend_symtable_to_proptable(Z_ARR_P(expr));
+                                       if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
+                                               /* TODO: try not to duplicate immutable arrays as well ??? */
+                                               ht = zend_array_dup(ht);
+                                       }
+                                       Z_OBJ_P(result)->properties = ht;
+                               } else if (Z_TYPE_P(expr) != IS_NULL) {
+                                       Z_OBJ_P(result)->properties = ht = zend_new_array(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);
+                                       } else {
+                                               if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                        }
-                               } else {
-                                       ZVAL_COPY(result, expr);
-                                       convert_to_object(result);
                                }
                        }
        }
@@ -37177,6 +37189,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
 
        zval *expr;
        zval *result = EX_VAR(opline->result.var);
+       HashTable *ht;
 
        SAVE_OPLINE();
        expr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@@ -37216,7 +37229,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
                        if (opline->extended_value == IS_ARRAY) {
                                if (Z_TYPE_P(expr) != IS_OBJECT) {
                                        if (Z_TYPE_P(expr) != IS_NULL) {
-                                               ZVAL_ARR(result, zend_new_array(8));
+                                               ZVAL_ARR(result, zend_new_array(1));
                                                expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr);
                                                if (IS_CV == IS_CONST) {
                                                        if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
@@ -37232,19 +37245,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCO
                                        convert_to_array(result);
                                }
                        } else {
-                               if (Z_TYPE_P(expr) != IS_ARRAY) {
-                                       object_init(result);
-                                       if (Z_TYPE_P(expr) != IS_NULL) {
-                                               expr = zend_hash_add_new(Z_OBJPROP_P(result), ZSTR_KNOWN(ZEND_STR_SCALAR), expr);
-                                               if (IS_CV == IS_CONST) {
-                                                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(expr))) Z_ADDREF_P(expr);
-                                               } else {
-                                                       if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
-                                               }
+                               ZVAL_OBJ(result, zend_objects_new(zend_standard_class_def));
+                               if (Z_TYPE_P(expr) == IS_ARRAY) {
+                                       ht = zend_symtable_to_proptable(Z_ARR_P(expr));
+                                       if (GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) {
+                                               /* TODO: try not to duplicate immutable arrays as well ??? */
+                                               ht = zend_array_dup(ht);
+                                       }
+                                       Z_OBJ_P(result)->properties = ht;
+                               } else if (Z_TYPE_P(expr) != IS_NULL) {
+                                       Z_OBJ_P(result)->properties = ht = zend_new_array(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);
+                                       } else {
+                                               if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr);
                                        }
-                               } else {
-                                       ZVAL_COPY(result, expr);
-                                       convert_to_object(result);
                                }
                        }
        }