diff --git a/ext/opcache/jit/zend_jit.h b/ext/opcache/jit/zend_jit.h index 09380f14ebe59..029bdd9a510a3 100644 --- a/ext/opcache/jit/zend_jit.h +++ b/ext/opcache/jit/zend_jit.h @@ -115,6 +115,7 @@ typedef struct _zend_jit_globals { 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_long max_polymorphic_calls; /* max number of inlined polymorphic calls */ + zend_long max_trace_length; /* max length of a single trace */ zend_sym_node *symbols; /* symbols for disassembler */ diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index ea23b4b2ed815..d78cde95e9641 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -360,7 +360,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN trace_buffer[idx].info = _op | (_info); \ trace_buffer[idx].ptr = _ptr; \ idx++; \ - if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 2) { \ + if (idx >= JIT_G(max_trace_length) - 2) { \ stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \ break; \ } @@ -372,7 +372,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN trace_buffer[idx].op3_type = _op3_type; \ trace_buffer[idx].ptr = _ptr; \ idx++; \ - if (idx >= ZEND_JIT_TRACE_MAX_LENGTH - 2) { \ + if (idx >= JIT_G(max_trace_length) - 2) { \ stop = ZEND_JIT_TRACE_STOP_TOO_LONG; \ break; \ } diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index a50110b17572f..6b1c872fe0520 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -258,6 +258,19 @@ static ZEND_INI_MH(OnUpdateUnrollL) ZEND_JIT_TRACE_MAX_LOOPS_UNROLL); return FAILURE; } + +static ZEND_INI_MH(OnUpdateMaxTraceLength) +{ + zend_long val = zend_ini_parse_quantity_warn(new_value, entry->name); + if (val > 3 && val <= ZEND_JIT_TRACE_MAX_LENGTH) { + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); + *p = val; + return SUCCESS; + } + zend_error(E_WARNING, "Invalid \"%s\" setting. Should be between 4 and %d", ZSTR_VAL(entry->name), + ZEND_JIT_TRACE_MAX_LENGTH); + return FAILURE; +} #endif ZEND_INI_BEGIN() @@ -336,6 +349,7 @@ ZEND_INI_BEGIN() 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) STD_PHP_INI_ENTRY("opcache.jit_max_polymorphic_calls" , "2", PHP_INI_ALL, OnUpdateLong, max_polymorphic_calls, zend_jit_globals, jit_globals) + STD_PHP_INI_ENTRY("opcache.jit_max_trace_length" , "1024", PHP_INI_ALL, OnUpdateMaxTraceLength, max_trace_length, zend_jit_globals, jit_globals) #endif ZEND_INI_END() @@ -849,6 +863,7 @@ ZEND_FUNCTION(opcache_get_configuration) 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)); + add_assoc_long(&directives, "opcache.jit_max_trace_length", JIT_G(max_trace_length)); #endif add_assoc_zval(return_value, "directives", &directives);