xref: /php-src/ext/opcache/jit/zend_jit.h (revision fa512dc4)
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 ZEND_EXT_API int  zend_jit_op_array(zend_op_array *op_array, zend_script *script);
154 ZEND_EXT_API int  zend_jit_script(zend_script *script);
155 ZEND_EXT_API void zend_jit_unprotect(void);
156 ZEND_EXT_API void zend_jit_protect(void);
157 ZEND_EXT_API void zend_jit_init(void);
158 ZEND_EXT_API int  zend_jit_config(zend_string *jit_options, int stage);
159 ZEND_EXT_API int  zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage);
160 ZEND_EXT_API int  zend_jit_check_support(void);
161 ZEND_EXT_API void zend_jit_startup(void *jit_buffer, size_t size, bool reattached);
162 ZEND_EXT_API void zend_jit_shutdown(void);
163 ZEND_EXT_API void zend_jit_activate(void);
164 ZEND_EXT_API void zend_jit_deactivate(void);
165 ZEND_EXT_API void zend_jit_status(zval *ret);
166 ZEND_EXT_API void zend_jit_restart(void);
167 
168 #define ZREG_LOAD           (1<<0)
169 #define ZREG_STORE          (1<<1)
170 #define ZREG_LAST_USE       (1<<2)
171 
172 #define ZREG_PI             (1<<3)
173 #define ZREG_PHI            (1<<4)
174 #define ZREG_FORWARD        (1<<5)
175 
176 #define ZREG_SPILL_SLOT     (1<<3)
177 
178 #define ZREG_CONST          (1<<4)
179 #define ZREG_ZVAL_COPY      (2<<4)
180 #define ZREG_TYPE_ONLY      (3<<4)
181 #define ZREG_ZVAL_ADDREF    (4<<4)
182 #define ZREG_THIS           (5<<4)
183 
184 #define ZREG_NONE           -1
185 
186 #endif /* HAVE_JIT_H */
187