From: Dmitry Stogov Date: Thu, 5 Jul 2018 22:25:24 +0000 (+0300) Subject: Optimize object to array casting X-Git-Tag: php-7.3.0alpha4~110 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85b2bc38e15688caa59f3545159d6141af4dfe9b;p=php Optimize object to array casting --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 5fb94b142e..4db0e7beba 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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); } } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 7aeb0a7d39..f1cd5c17d7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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); } } }