From: Dmitry Stogov Date: Wed, 21 Feb 2018 09:07:29 +0000 (+0300) Subject: Mark exceptional helpers as "cold" X-Git-Tag: php-7.3.0alpha1~322 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c0427cada37c48e8d626efd87f4685c82403e4a;p=php Mark exceptional helpers as "cold" --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 83da0db29d..58a4fa226b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -633,7 +633,7 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v ZVAL_REF(variable_ptr, ref); } -static zend_never_inline int zend_wrong_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr, zend_uchar value_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD int zend_wrong_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr, zend_uchar value_type OPLINE_DC EXECUTE_DATA_DC) { zend_error(E_NOTICE, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 00fe284fb0..a1aa541362 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -172,7 +172,7 @@ ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HELPER(zend_mod_by_zero_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_mod_by_zero_helper, ANY, ANY) { USE_OPLINE @@ -758,7 +758,7 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER(zend_this_not_in_object_context_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_this_not_in_object_context_helper, ANY, ANY) { USE_OPLINE @@ -772,7 +772,7 @@ ZEND_VM_HELPER(zend_this_not_in_object_context_helper, ANY, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HELPER(zend_abstract_method_helper, ANY, ANY, zend_function *fbc) +ZEND_VM_COLD_HELPER(zend_abstract_method_helper, ANY, ANY, zend_function *fbc) { USE_OPLINE @@ -782,7 +782,7 @@ ZEND_VM_HELPER(zend_abstract_method_helper, ANY, ANY, zend_function *fbc) HANDLE_EXCEPTION(); } -ZEND_VM_HELPER(zend_undefined_function_helper, ANY, ANY, zval *function_name) +ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY, zval *function_name) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); @@ -1746,7 +1746,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY) { USE_OPLINE @@ -1758,7 +1758,7 @@ ZEND_VM_HELPER(zend_use_tmp_in_write_context_helper, ANY, ANY) HANDLE_EXCEPTION(); } -ZEND_VM_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY) { USE_OPLINE @@ -4196,7 +4196,7 @@ ZEND_VM_HOT_HANDLER(65, ZEND_SEND_VAL, CONST|TMPVAR, NUM) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER(zend_cannot_pass_by_ref_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_cannot_pass_by_ref_helper, ANY, ANY) { USE_OPLINE zval *arg; @@ -7209,7 +7209,7 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HELPER(zend_yield_in_closed_generator_helper, ANY, ANY) +ZEND_VM_COLD_HELPER(zend_yield_in_closed_generator_helper, ANY, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 11125a906b..08a6c31fb8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -431,7 +431,7 @@ typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *opcode_handler_t) (ZEND_OPCODE_H static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS); static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_by_zero_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_by_zero_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -441,7 +441,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_mod_by_zero_helper_SPEC(ZEND_O HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -455,7 +455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_this_not_in_object_context_hel HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_abstract_method_helper_SPEC(zend_function *fbc ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_abstract_method_helper_SPEC(zend_function *fbc ZEND_OPCODE_HANDLER_ARGS_DC) { USE_OPLINE @@ -465,14 +465,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_abstract_method_helper_SPEC(ze HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_undefined_function_helper_SPEC(zval *function_name ZEND_OPCODE_HANDLER_ARGS_DC) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_undefined_function_helper_SPEC(zval *function_name ZEND_OPCODE_HANDLER_ARGS_DC) { SAVE_OPLINE(); zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -484,7 +484,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_tmp_in_write_context_helpe HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -1233,7 +1233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER( } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *arg; @@ -1843,7 +1843,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_ } } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index aa8df9d95d..a4a07510f7 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -1083,7 +1083,7 @@ function gen_handler($f, $spec, $kind, $name, $op1, $op2, $use, $code, $lineno, } // Generates helper -function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $extra_spec = null) { +function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, $inline, $cold, $extra_spec = null) { global $definition_file, $prefix; if ($kind == ZEND_VM_KIND_HYBRID) { @@ -1104,18 +1104,22 @@ function gen_helper($f, $spec, $kind, $name, $op1, $op2, $param, $code, $lineno, switch($kind) { case ZEND_VM_KIND_CALL: if ($inline) { - $zend_always_inline = " zend_always_inline"; + $zend_attributes = " zend_always_inline"; $zend_fastcall = ""; } else { - $zend_always_inline = ""; + if ($cold) { + $zend_attributes = " zend_never_inline ZEND_COLD"; + } else { + $zend_attributes = ""; + } $zend_fastcall = " ZEND_FASTCALL"; } if ($param == null) { // Helper without parameters - out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS)\n"); + out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name(ZEND_OPCODE_HANDLER_ARGS)\n"); } else { // Helper with parameter - out($f, "static$zend_always_inline ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name($param ZEND_OPCODE_HANDLER_ARGS_DC)\n"); + out($f, "static$zend_attributes ZEND_OPCODE_HANDLER_RET$zend_fastcall $spec_name($param ZEND_OPCODE_HANDLER_ARGS_DC)\n"); } break; case ZEND_VM_KIND_SWITCH: @@ -1588,7 +1592,7 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array()) if (isset($helpers[$num]["op1"][$op1]) && isset($helpers[$num]["op2"][$op2])) { // Generate helper code - gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $extra_spec); + gen_helper($f, 1, $kind, $num, $op1, $op2, $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"], $helpers[$num]["cold"], $extra_spec); } } } else { @@ -2285,15 +2289,18 @@ function gen_vm($def, $skel) { $handler = $code; $helper = null; $list[$lineno] = array("handler"=>$handler); - } else if (strpos($line,"ZEND_VM_HELPER(") === 0 || strpos($line,"ZEND_VM_INLINE_HELPER(") === 0) { + } else if (strpos($line,"ZEND_VM_HELPER(") === 0 || + strpos($line,"ZEND_VM_INLINE_HELPER(") === 0 || + strpos($line,"ZEND_VM_COLD_HELPER(") === 0) { // Parsing helper's definition if (preg_match( - "/^ZEND_VM(_INLINE)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/", + "/^ZEND_VM(_INLINE|_COLD)?_HELPER\(\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(?:,\s*SPEC\(([A-Z_|=,]+)\)\s*)?(?:,\s*([^)]*)\s*)?\)/", $line, $m) == 0) { die("ERROR ($def:$lineno): Invalid ZEND_VM_HELPER definition.\n"); } - $inline = !empty($m[1]); + $inline = !empty($m[1]) && $m[1] === "_INLINE"; + $cold = !empty($m[1]) && $m[1] === "_COLD"; $helper = $m[2]; $op1 = parse_operand_spec($def, $lineno, $m[3], $flags1); $op2 = parse_operand_spec($def, $lineno, $m[4], $flags2); @@ -2310,7 +2317,7 @@ function gen_vm($def, $skel) { } } - $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline); + $helpers[$helper] = array("op1"=>$op1,"op2"=>$op2,"param"=>$param,"code"=>"","inline"=>$inline,"cold"=>$cold); if (!empty($m[5])) { $helpers[$helper]["spec"] = parse_spec_rules($def, $lineno, $m[5]);