]> granicus.if.org Git - php/commitdiff
Mark exceptional helpers as "cold"
authorDmitry Stogov <dmitry@zend.com>
Wed, 21 Feb 2018 09:07:29 +0000 (12:07 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 21 Feb 2018 09:07:29 +0000 (12:07 +0300)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 83da0db29dd3c1b213ac670a39a5a143a1502ec0..58a4fa226b002523665a78b13a675d951c2c0501 100644 (file)
@@ -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)) {
index 00fe284fb0dcfd726afd4278c118f69c3dcb981e..a1aa541362c419dab926ca69ed05350f9ab6465e 100644 (file)
@@ -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
 
index 11125a906baff6b9c171b2cc4c9a3ab80a363057..08a6c31fb8612dabcf70f124bae9d4f80950303b 100644 (file)
@@ -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
 
index aa8df9d95d1a1a4bff302a8e20364752ac4eb36b..a4a07510f71bbf0692f9769be7314c31b8be55f3 100644 (file)
@@ -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]);