1 /* 2 +----------------------------------------------------------------------+ 3 | Zend JIT | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | https://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Dmitry Stogov <dmitry@php.net> | 16 +----------------------------------------------------------------------+ 17 */ 18 19 #ifndef HAVE_JIT_H 20 #define HAVE_JIT_H 21 22 #if defined(__x86_64__) || defined(i386) || defined(ZEND_WIN32) 23 # define ZEND_JIT_TARGET_X86 1 24 # define ZEND_JIT_TARGET_ARM64 0 25 #elif defined (__aarch64__) 26 # define ZEND_JIT_TARGET_X86 0 27 # define ZEND_JIT_TARGET_ARM64 1 28 #else 29 # error "JIT not supported on this platform" 30 #endif 31 32 #define ZEND_JIT_LEVEL_NONE 0 /* no JIT */ 33 #define ZEND_JIT_LEVEL_MINIMAL 1 /* minimal JIT (subroutine threading) */ 34 #define ZEND_JIT_LEVEL_INLINE 2 /* selective inline threading */ 35 #define ZEND_JIT_LEVEL_OPT_FUNC 3 /* optimized JIT based on Type-Inference */ 36 #define ZEND_JIT_LEVEL_OPT_FUNCS 4 /* optimized JIT based on Type-Inference and call-tree */ 37 #define ZEND_JIT_LEVEL_OPT_SCRIPT 5 /* optimized JIT based on Type-Inference and inner-procedure analysis */ 38 39 #define ZEND_JIT_ON_SCRIPT_LOAD 0 40 #define ZEND_JIT_ON_FIRST_EXEC 1 41 #define ZEND_JIT_ON_PROF_REQUEST 2 /* compile the most frequently caled on first request functions */ 42 #define ZEND_JIT_ON_HOT_COUNTERS 3 /* compile functions after N calls or loop iterations */ 43 #define ZEND_JIT_ON_DOC_COMMENT 4 /* compile functions with "@jit" tag in doc-comments */ 44 #define ZEND_JIT_ON_HOT_TRACE 5 /* trace functions after N calls or loop iterations */ 45 46 #define ZEND_JIT_REG_ALLOC_LOCAL (1<<0) /* local linear scan register allocation */ 47 #define ZEND_JIT_REG_ALLOC_GLOBAL (1<<1) /* global linear scan register allocation */ 48 #define ZEND_JIT_CPU_AVX (1<<2) /* use AVX instructions, if available */ 49 50 #define ZEND_JIT_DEFAULT_BUFFER_SIZE "64M" 51 52 #define ZEND_JIT_COUNTER_INIT 32531 53 54 #define ZEND_JIT_DEBUG_ASM (1<<0) 55 #define ZEND_JIT_DEBUG_SSA (1<<1) 56 #define ZEND_JIT_DEBUG_REG_ALLOC (1<<2) 57 #define ZEND_JIT_DEBUG_ASM_STUBS (1<<3) 58 59 #define ZEND_JIT_DEBUG_PERF (1<<4) 60 #define ZEND_JIT_DEBUG_PERF_DUMP (1<<5) 61 #define ZEND_JIT_DEBUG_VTUNE (1<<7) 62 63 #define ZEND_JIT_DEBUG_GDB (1<<8) 64 #define ZEND_JIT_DEBUG_SIZE (1<<9) 65 #define ZEND_JIT_DEBUG_ASM_ADDR (1<<10) 66 67 #define ZEND_JIT_DEBUG_TRACE_START (1<<12) 68 #define ZEND_JIT_DEBUG_TRACE_STOP (1<<13) 69 #define ZEND_JIT_DEBUG_TRACE_COMPILED (1<<14) 70 #define ZEND_JIT_DEBUG_TRACE_EXIT (1<<15) 71 #define ZEND_JIT_DEBUG_TRACE_ABORT (1<<16) 72 #define ZEND_JIT_DEBUG_TRACE_BLACKLIST (1<<17) 73 #define ZEND_JIT_DEBUG_TRACE_BYTECODE (1<<18) 74 #define ZEND_JIT_DEBUG_TRACE_TSSA (1<<19) 75 #define ZEND_JIT_DEBUG_TRACE_EXIT_INFO (1<<20) 76 77 #define ZEND_JIT_DEBUG_IR_SRC (1<<24) 78 #define ZEND_JIT_DEBUG_IR_FINAL (1<<25) 79 #define ZEND_JIT_DEBUG_IR_AFTER_SCCP (1<<26) 80 #define ZEND_JIT_DEBUG_IR_AFTER_CFG (1<<27) 81 82 #define ZEND_JIT_DEBUG_IR_AFTER_GCM (1<<28) 83 #define ZEND_JIT_DEBUG_IR_AFTER_SCHEDULE (1<<29) 84 #define ZEND_JIT_DEBUG_IR_AFTER_REGS (1<<30) 85 #define ZEND_JIT_DEBUG_IR_CODEGEN (1U<<31) 86 87 #define ZEND_JIT_DEBUG_PERSISTENT 0x1f0 /* profile and debugger flags can't be changed at run-time */ 88 89 #define ZEND_JIT_TRACE_MAX_LENGTH 1024 /* max length of single trace */ 90 #define ZEND_JIT_TRACE_MAX_EXITS 512 /* max number of side exits per trace */ 91 92 #define ZEND_JIT_TRACE_MAX_FUNCS 30 /* max number of different functions in a single trace */ 93 #define ZEND_JIT_TRACE_MAX_CALL_DEPTH 10 /* max depth of inlined calls */ 94 #define ZEND_JIT_TRACE_MAX_RET_DEPTH 4 /* max depth of inlined returns */ 95 #define ZEND_JIT_TRACE_MAX_LOOPS_UNROLL 10 /* max number of unrolled loops */ 96 97 #define ZEND_JIT_TRACE_BAD_ROOT_SLOTS 64 /* number of slots in bad root trace cache */ 98 99 typedef struct _zend_jit_trace_rec zend_jit_trace_rec; 100 typedef struct _zend_jit_trace_stack_frame zend_jit_trace_stack_frame; 101 typedef struct _sym_node zend_sym_node; 102 103 typedef struct _zend_jit_globals { 104 bool enabled; 105 bool on; 106 uint8_t trigger; 107 uint8_t opt_level; 108 uint32_t opt_flags; 109 110 const char *options; 111 zend_long buffer_size; 112 zend_long debug; 113 zend_long bisect_limit; 114 double prof_threshold; 115 zend_long max_root_traces; /* max number of root traces */ 116 zend_long max_side_traces; /* max number of side traces (per root trace) */ 117 zend_long max_exit_counters; /* max total number of side exits for all traces */ 118 zend_long hot_loop; 119 zend_long hot_func; 120 zend_long hot_return; 121 zend_long hot_side_exit; /* number of exits before taking side trace */ 122 zend_long blacklist_root_trace; /* number of attempts to JIT a root trace before blacklist it */ 123 zend_long blacklist_side_trace; /* number of attempts to JIT a side trace before blacklist it */ 124 zend_long max_loop_unrolls; /* max number of unrolled loops */ 125 zend_long max_recursive_calls; /* max number of recursive inlined call unrolls */ 126 zend_long max_recursive_returns; /* max number of recursive inlined return unrolls */ 127 zend_long max_polymorphic_calls; /* max number of inlined polymorphic calls */ 128 zend_long max_trace_length; /* max length of a single trace */ 129 130 zend_sym_node *symbols; /* symbols for disassembler */ 131 132 bool tracing; 133 134 zend_jit_trace_rec *current_trace; 135 zend_jit_trace_stack_frame *current_frame; 136 137 const zend_op *bad_root_cache_opline[ZEND_JIT_TRACE_BAD_ROOT_SLOTS]; 138 uint8_t bad_root_cache_count[ZEND_JIT_TRACE_BAD_ROOT_SLOTS]; 139 uint8_t bad_root_cache_stop[ZEND_JIT_TRACE_BAD_ROOT_SLOTS]; 140 uint32_t bad_root_slot; 141 142 uint8_t *exit_counters; 143 } zend_jit_globals; 144 145 #ifdef ZTS 146 # define JIT_G(v) ZEND_TSRMG(jit_globals_id, zend_jit_globals *, v) 147 extern int jit_globals_id; 148 #else 149 # define JIT_G(v) (jit_globals.v) 150 extern zend_jit_globals jit_globals; 151 #endif 152 153 int zend_jit_op_array(zend_op_array *op_array, zend_script *script); 154 int zend_jit_script(zend_script *script); 155 void zend_jit_unprotect(void); 156 void zend_jit_protect(void); 157 void zend_jit_init(void); 158 int zend_jit_config(zend_string *jit_options, int stage); 159 int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage); 160 int zend_jit_check_support(void); 161 void zend_jit_startup(void *jit_buffer, size_t size, bool reattached); 162 void zend_jit_shutdown(void); 163 void zend_jit_activate(void); 164 void zend_jit_deactivate(void); 165 ZEND_EXT_API void zend_jit_status(zval *ret); 166 ZEND_EXT_API void zend_jit_blacklist_function(zend_op_array *op_array); 167 void zend_jit_restart(void); 168 169 #define ZREG_LOAD (1<<0) 170 #define ZREG_STORE (1<<1) 171 #define ZREG_LAST_USE (1<<2) 172 173 #define ZREG_PI (1<<3) 174 #define ZREG_PHI (1<<4) 175 #define ZREG_FORWARD (1<<5) 176 177 #define ZREG_SPILL_SLOT (1<<3) 178 179 #define ZREG_CONST (1<<4) 180 #define ZREG_ZVAL_COPY (2<<4) 181 #define ZREG_TYPE_ONLY (3<<4) 182 #define ZREG_ZVAL_ADDREF (4<<4) 183 #define ZREG_THIS (5<<4) 184 185 #define ZREG_NONE -1 186 187 #endif /* HAVE_JIT_H */ 188