From: Dmitry Stogov Date: Thu, 28 May 2020 09:28:05 +0000 (+0300) Subject: Split "opcache.jit_max_recursion_unroll" into "opcache.jit_max_recursive_calls" and... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=efbe96166dc32f85e57e2c23e0c1440488a42432;p=php Split "opcache.jit_max_recursion_unroll" into "opcache.jit_max_recursive_calls" and "opcache.jit_max_recursive_returns". It's possible to disable recording of "recursive return loops" setting opcache.jit_max_recursive_returns to 0. --- diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 50f696027d..a86341ba76 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -93,18 +93,19 @@ typedef struct _zend_jit_globals { zend_long debug; zend_long bisect_limit; double prof_threshold; - zend_long max_root_traces; /* max number of root traces */ - zend_long max_side_traces; /* max number of side traces (per root trace) */ + zend_long max_root_traces; /* max number of root traces */ + zend_long max_side_traces; /* max number of side traces (per root trace) */ zend_long hot_loop; zend_long hot_func; zend_long hot_return; - zend_long hot_side_exit; /* number of exits before taking side trace */ - zend_long blacklist_root_trace; /* number of attempts to JIT a root trace before blacklist it */ - zend_long blacklist_side_trace; /* number of attempts to JIT a side trace before blacklist it */ - zend_long max_recursion_unroll; /* max number of recursive inlined calls/returns unrolls */ - zend_long max_loops_unroll; /* max number of unrolled loops */ - - zend_sym_node *symbols; /* symbols for disassembler */ + zend_long hot_side_exit; /* number of exits before taking side trace */ + zend_long blacklist_root_trace; /* number of attempts to JIT a root trace before blacklist it */ + zend_long blacklist_side_trace; /* number of attempts to JIT a side trace before blacklist it */ + zend_long max_loops_unroll; /* max number of unrolled loops */ + zend_long max_recursive_calls; /* max number of recursive inlined call unrolls */ + zend_long max_recursive_returns; /* max number of recursive inlined return unrolls */ + + zend_sym_node *symbols; /* symbols for disassembler */ zend_jit_trace_rec *current_trace; zend_jit_trace_stack_frame *current_frame; diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 04eb311cd7..54fa6d21fd 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -365,10 +365,6 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN trace_buffer[idx].level = trace_buffer[0].level = ret_level ? ret_level + 1 : 0; \ trace_buffer[idx].ptr = _ptr; -#ifndef ZEND_JIT_RECORD_RECURSIVE_RETURN -# define ZEND_JIT_RECORD_RECURSIVE_RETURN 1 -#endif - static int zend_jit_trace_recursive_call_count(const zend_op_array *op_array, const zend_op_array **unrolled_calls, int ret_level, int level) { int i; @@ -690,12 +686,12 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, count = zend_jit_trace_recursive_call_count(&EX(func)->op_array, unrolled_calls, ret_level, level); if (opline == orig_opline) { - if (count + 1 >= JIT_G(max_recursion_unroll)) { + if (count + 1 >= JIT_G(max_recursive_calls)) { stop = ZEND_JIT_TRACE_STOP_RECURSIVE_CALL; break; } backtrack_recursion = idx; - } else if (count >= JIT_G(max_recursion_unroll)) { + } else if (count >= JIT_G(max_recursive_calls)) { stop = ZEND_JIT_TRACE_STOP_DEEP_RECURSION; break; } @@ -709,8 +705,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (is_toplevel) { stop = ZEND_JIT_TRACE_STOP_TOPLEVEL; break; -#if ZEND_JIT_RECORD_RECURSIVE_RETURN } else if (start == ZEND_JIT_TRACE_START_RETURN + && JIT_G(max_recursive_returns) > 0 && execute_data->prev_execute_data && execute_data->prev_execute_data->func && execute_data->prev_execute_data->func->type == ZEND_USER_FUNCTION @@ -722,13 +718,13 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, TRACE_RECORD(ZEND_JIT_TRACE_BACK, 0, &EX(func)->op_array); count = zend_jit_trace_recursive_ret_count(&EX(func)->op_array, unrolled_calls, ret_level); if (opline == orig_opline) { - if (count + 1 >= JIT_G(max_recursion_unroll)) { + if (count + 1 >= JIT_G(max_recursive_returns)) { stop = ZEND_JIT_TRACE_STOP_RECURSIVE_RET; break; } backtrack_ret_recursion = idx; backtrack_ret_recursion_level = ret_level; - } else if (count >= JIT_G(max_recursion_unroll)) { + } else if (count >= JIT_G(max_recursive_returns)) { stop = ZEND_JIT_TRACE_STOP_DEEP_RECURSION; break; } @@ -740,7 +736,6 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (prev_call) { idx = zend_jit_trace_record_fake_init_call(prev_call, trace_buffer, idx); } -#endif } else if (start & ZEND_JIT_TRACE_START_LOOP && !zend_jit_trace_bad_loop_exit(orig_opline)) { /* Fail to try close the loop. diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 7ff085c059..dd03e8170a 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -227,16 +227,29 @@ static ZEND_INI_MH(OnUpdateCounter) return FAILURE; } -static ZEND_INI_MH(OnUpdateUnrollR) +static ZEND_INI_MH(OnUpdateUnrollC) { zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); - if (val > 0 && val < ZEND_JIT_TRACE_MAX_CALL_DEPTH && val < ZEND_JIT_TRACE_MAX_RET_DEPTH) { + if (val > 0 && val < ZEND_JIT_TRACE_MAX_CALL_DEPTH) { zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); *p = val; return SUCCESS; } zend_error(E_WARNING, "Invalid \"%s\" setting. Should be between 1 and %d", ZSTR_VAL(entry->name), - MIN(ZEND_JIT_TRACE_MAX_CALL_DEPTH, ZEND_JIT_TRACE_MAX_CALL_DEPTH)); + ZEND_JIT_TRACE_MAX_CALL_DEPTH); + return FAILURE; +} + +static ZEND_INI_MH(OnUpdateUnrollR) +{ + zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); + if (val >= 0 && val < ZEND_JIT_TRACE_MAX_RET_DEPTH) { + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = val; + return SUCCESS; + } + zend_error(E_WARNING, "Invalid \"%s\" setting. Should be between 0 and %d", ZSTR_VAL(entry->name), + ZEND_JIT_TRACE_MAX_RET_DEPTH); return FAILURE; } @@ -312,21 +325,22 @@ ZEND_INI_BEGIN() STD_PHP_INI_ENTRY("opcache.cache_id" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.cache_id, zend_accel_globals, accel_globals) #endif #ifdef HAVE_JIT - STD_PHP_INI_ENTRY("opcache.jit" , ZEND_JIT_DEFAULT_OPTIONS, PHP_INI_ALL, OnUpdateJit, options, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_buffer_size" , ZEND_JIT_DEFAULT_BUFFER_SIZE, PHP_INI_SYSTEM, OnUpdateLong, buffer_size, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_debug" , "0", PHP_INI_ALL, OnUpdateJitDebug, debug, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_bisect_limit" , "0", PHP_INI_ALL, OnUpdateLong, bisect_limit, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_prof_threshold" , "0.005", PHP_INI_ALL, OnUpdateReal, prof_threshold, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_max_root_traces" , "1024", PHP_INI_SYSTEM, OnUpdateLong, max_root_traces, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_max_side_traces" , "128", PHP_INI_SYSTEM, OnUpdateLong, max_side_traces, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_hot_loop" , "64", PHP_INI_SYSTEM, OnUpdateCounter, hot_loop, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_hot_func" , "127", PHP_INI_SYSTEM, OnUpdateCounter, hot_func, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_hot_return" , "8", PHP_INI_SYSTEM, OnUpdateCounter, hot_return, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_hot_side_exit" , "8", PHP_INI_ALL, OnUpdateCounter, hot_side_exit, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_blacklist_root_trace" , "16", PHP_INI_ALL, OnUpdateCounter, blacklist_root_trace, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_blacklist_side_trace" , "8", PHP_INI_ALL, OnUpdateCounter, blacklist_side_trace, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_max_recursion_unroll" , "2", PHP_INI_ALL, OnUpdateUnrollR, max_recursion_unroll, zend_jit_globals, jit_globals) - STD_PHP_INI_ENTRY("opcache.jit_max_loops_unroll" , "8", PHP_INI_ALL, OnUpdateUnrollL, max_loops_unroll, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit" , ZEND_JIT_DEFAULT_OPTIONS, PHP_INI_ALL, OnUpdateJit, options, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_buffer_size" , ZEND_JIT_DEFAULT_BUFFER_SIZE, PHP_INI_SYSTEM, OnUpdateLong, buffer_size, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_debug" , "0", PHP_INI_ALL, OnUpdateJitDebug, debug, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_bisect_limit" , "0", PHP_INI_ALL, OnUpdateLong, bisect_limit, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_prof_threshold" , "0.005", PHP_INI_ALL, OnUpdateReal, prof_threshold, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_root_traces" , "1024", PHP_INI_SYSTEM, OnUpdateLong, max_root_traces, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_side_traces" , "128", PHP_INI_SYSTEM, OnUpdateLong, max_side_traces, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_hot_loop" , "64", PHP_INI_SYSTEM, OnUpdateCounter, hot_loop, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_hot_func" , "127", PHP_INI_SYSTEM, OnUpdateCounter, hot_func, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_hot_return" , "8", PHP_INI_SYSTEM, OnUpdateCounter, hot_return, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_hot_side_exit" , "8", PHP_INI_ALL, OnUpdateCounter, hot_side_exit, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_blacklist_root_trace" , "16", PHP_INI_ALL, OnUpdateCounter, blacklist_root_trace, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_blacklist_side_trace" , "8", PHP_INI_ALL, OnUpdateCounter, blacklist_side_trace, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_loops_unroll" , "8", PHP_INI_ALL, OnUpdateUnrollL, max_loops_unroll, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_recursive_calls" , "2", PHP_INI_ALL, OnUpdateUnrollC, max_recursive_calls, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_recursive_returns" , "2", PHP_INI_ALL, OnUpdateUnrollR, max_recursive_returns, zend_jit_globals, jit_globals) #endif ZEND_INI_END() @@ -810,7 +824,8 @@ ZEND_FUNCTION(opcache_get_configuration) add_assoc_long(&directives, "opcache.jit_hot_return", JIT_G(hot_return)); add_assoc_long(&directives, "opcache.jit_hot_side_exit", JIT_G(hot_side_exit)); add_assoc_long(&directives, "opcache.jit_max_loops_unroll", JIT_G(max_loops_unroll)); - add_assoc_long(&directives, "opcache.jit_max_recursion_unroll", JIT_G(max_recursion_unroll)); + add_assoc_long(&directives, "opcache.jit_max_recursive_calls", JIT_G(max_recursive_calls)); + add_assoc_long(&directives, "opcache.jit_max_recursive_returns", JIT_G(max_recursive_returns)); add_assoc_long(&directives, "opcache.jit_max_root_traces", JIT_G(max_root_traces)); add_assoc_long(&directives, "opcache.jit_max_side_traces", JIT_G(max_side_traces)); add_assoc_long(&directives, "opcache.jit_prof_threshold", JIT_G(prof_threshold));