45#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
56#define ZEND_JIT_USE_RC_INFERENCE
58#ifdef ZEND_JIT_USE_RC_INFERENCE
59# define ZEND_SSA_RC_INFERENCE_FLAG ZEND_SSA_RC_INFERENCE
60# define RC_MAY_BE_1(info) (((info) & (MAY_BE_RC1|MAY_BE_REF)) != 0)
61# define RC_MAY_BE_N(info) (((info) & (MAY_BE_RCN|MAY_BE_REF)) != 0)
63# define ZEND_SSA_RC_INFERENCE_FLAG 0
64# define RC_MAY_BE_1(info) 1
65# define RC_MAY_BE_N(info) 1
68#define JIT_PREFIX "JIT$"
69#define JIT_STUB_PREFIX "JIT$$"
70#define TRACE_PREFIX "TRACE-"
80static int zend_jit_vm_kind = 0;
81#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
82static int zend_write_protect = 1;
85static void *dasm_buf =
NULL;
86static void *dasm_end =
NULL;
87static void **dasm_ptr =
NULL;
89static size_t dasm_size = 0;
93static const void *zend_jit_runtime_jit_handler =
NULL;
94static const void *zend_jit_profile_jit_handler =
NULL;
95static const void *zend_jit_func_hot_counter_handler =
NULL;
96static const void *zend_jit_loop_hot_counter_handler =
NULL;
97static const void *zend_jit_func_trace_counter_handler =
NULL;
98static const void *zend_jit_ret_trace_counter_handler =
NULL;
99static const void *zend_jit_loop_trace_counter_handler =
NULL;
103static int zend_jit_trace_op_len(
const zend_op *opline);
105static uint32_t zend_jit_trace_get_exit_point(
const zend_op *to_opline, uint32_t
flags);
106static const void *zend_jit_trace_get_exit_addr(uint32_t
n);
107static void zend_jit_trace_add_code(
const void *
start, uint32_t
size);
111static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t op2_info);
114 while (blocks[b].level > blocks[
a].level) {
120static bool zend_ssa_is_last_use(
const zend_op_array *op_array,
const zend_ssa *ssa,
int var,
int use)
130 phi = zend_ssa_next_use_phi(ssa, var, phi);
136 int b = ssa->
cfg.
map[use];
146 if (dominates(ssa->
cfg.
blocks, def_block,
151 while (prev_use >= 0 && prev_use != use) {
152 if (b != ssa->
cfg.
map[prev_use]
154 && !zend_ssa_is_no_val_use(op_array->
opcodes + prev_use, ssa->
ops + prev_use, var)) {
157 prev_use = zend_ssa_next_use(ssa->
ops, var, prev_use);
161 next_use = zend_ssa_next_use(ssa->
ops, var, use);
164 }
else if (zend_ssa_is_no_val_use(op_array->
opcodes + next_use, ssa->
ops + next_use, var)) {
170static int zend_jit_is_constant_cmp_long_long(
const zend_op *opline,
183 op1_min = op1_range->
min;
184 op1_max = op1_range->
max;
193 op2_min = op2_range->
min;
194 op2_max = op2_range->
max;
207 if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) {
210 }
else if (op1_max < op2_min || op1_min > op2_max) {
217 if (op1_min == op1_max && op2_min == op2_max && op1_min == op2_min) {
220 }
else if (op1_max < op2_min || op1_min > op2_max) {
226 if (op1_max < op2_min) {
229 }
else if (op1_min >= op2_max) {
235 if (op1_max <= op2_min) {
238 }
else if (op1_min > op2_max) {
249#define ADVANCE_SSA_OP(ssa_op, offset) \
251 if (ssa_op) ssa_op += offset; \
261 ADVANCE_SSA_OP(ssa_op, 1);
264 switch (
p->opline->opcode) {
317 ADVANCE_SSA_OP(ssa_op, zend_jit_trace_op_len(opline));
331 ADVANCE_SSA_OP(ssa_op, 1);
332 skip = (call_level == 1);
333 while (opline !=
end) {
394 ADVANCE_SSA_OP(ssa_op, 1);
408 ADVANCE_SSA_OP(ssa_op, 1);
409 skip = (call_level == 1);
410 while (opline !=
end) {
434 ADVANCE_SSA_OP(ssa_op, 1);
484#ifdef ZEND_JIT_USE_RC_INFERENCE
506static bool zend_jit_may_avoid_refcounting(
const zend_op *opline, uint32_t op1_info)
510 if (!
JIT_G(current_frame) ||
526 if (!
JIT_G(current_frame) ||
544static bool zend_jit_is_persistent_constant(
zval *
key, uint32_t
flags)
587 }
else if (parent->info.user.filename != filename) {
596 parent = parent->parent;
612 }
else if (on_this) {
613 if (ce == info->
ce) {
614 if (ce == op_array->
scope) {
653 (!on_this || info->
ce != ce)) {
660#define OP_RANGE(ssa_op, opN) \
661 (((opline->opN##_type & (IS_TMP_VAR|IS_VAR|IS_CV)) && \
663 (ssa_op)->opN##_use >= 0 && \
664 ssa->var_info[(ssa_op)->opN##_use].has_range) ? \
665 &ssa->var_info[(ssa_op)->opN##_use].range : NULL)
667#define OP1_RANGE() OP_RANGE(ssa_op, op1)
668#define OP2_RANGE() OP_RANGE(ssa_op, op2)
669#define OP1_DATA_RANGE() OP_RANGE(ssa_op + 1, op1)
674#ifdef HAVE_GCC_GLOBAL_REGS
675# define GCC_GLOBAL_REGS 1
677# define GCC_GLOBAL_REGS 0
683#ifndef PROFITABILITY_CHECKS
684# define PROFITABILITY_CHECKS 1
690#if defined(__clang__)
691# pragma clang diagnostic push
692# pragma clang diagnostic ignored "-Wtautological-compare"
693# pragma clang diagnostic ignored "-Wstring-compare"
698#if defined(__clang__)
699# pragma clang diagnostic pop
705# include <sys/mman.h>
706# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
707# define MAP_ANONYMOUS MAP_ANON
715 add_assoc_bool(&stats,
"enabled",
JIT_G(enabled));
716 add_assoc_bool(&stats,
"on",
JIT_G(on));
717 add_assoc_long(&stats,
"kind",
JIT_G(trigger));
718 add_assoc_long(&stats,
"opt_level",
JIT_G(opt_level));
719 add_assoc_long(&stats,
"opt_flags",
JIT_G(opt_flags));
721 add_assoc_long(&stats,
"buffer_size", (
char*)dasm_end - (
char*)dasm_buf);
722 add_assoc_long(&stats,
"buffer_free", (
char*)dasm_end - (
char*)*dasm_ptr);
724 add_assoc_long(&stats,
"buffer_size", 0);
725 add_assoc_long(&stats,
"buffer_free", 0);
727 add_assoc_zval(
ret,
"jit", &stats);
730static bool zend_jit_inc_call_level(uint8_t opcode)
748static bool zend_jit_dec_call_level(uint8_t opcode)
767 smart_str_appends(&
buf, JIT_PREFIX);
768 if (op_array->
scope) {
770 smart_str_appends(&
buf,
"::");
774 smart_str_appends(&
buf,
":");
776 smart_str_appends(&
buf,
":");
782 smart_str_appends(&
buf, JIT_PREFIX);
794 zend_long op1_min, op1_max, op2_min, op2_max;
840 if (zend_add_will_overflow(op1_min, op2_min)) {
852 if (zend_add_will_overflow(op1_max, op2_max)) {
867 if (zend_sub_will_overflow(op1_min, op2_max)) {
879 if (zend_sub_will_overflow(op1_max, op2_min)) {
901 if (zend_add_will_overflow(op1_min, op2_min)) {
913 if (zend_add_will_overflow(op1_max, op2_max)) {
928 if (zend_sub_will_overflow(op1_min, op2_max)) {
940 if (zend_sub_will_overflow(op1_max, op2_min)) {
986 if (zend_jit_build_cfg(op_array, &ssa->
cfg) !=
SUCCESS) {
992 if ((ssa->
cfg.
flags & ZEND_FUNC_HAS_EXTENDED_INFO)) {
1040 int candidates_count, i;
1043 checkpoint = zend_arena_checkpoint(
CG(
arena));
1045 candidates_count = 0;
1047 if (zend_jit_may_be_in_reg(op_array, ssa, i)) {
1052 if (!candidates_count) {
1053 zend_arena_release(&
CG(
arena), checkpoint);
1072 }
else if (ra[src].ref) {
1091 }
else if (ra[src].ref) {
1127 bool may_remove = 1;
1136 phi = zend_ssa_next_use_phi(ssa, i, phi);
1148 uint32_t var_num = ssa->
vars[i].
var;
1164 if (range->start > op_num) {
1178 }
while (op_num < range->
end);
1188 bool may_remove = 1;
1197 phi = zend_ssa_next_use_phi(ssa, i, phi);
1212 uint32_t var_num = ssa->
vars[i].
var;
1229static int zend_jit_compute_post_order(
zend_cfg *cfg,
int start,
int *post_order)
1238 zend_worklist_push(&worklist,
start);
1240 while (zend_worklist_len(&worklist) != 0) {
1242 b = zend_worklist_peek(&worklist);
1250 }
else if (zend_worklist_push(&worklist, *
p)) {
1257 zend_worklist_pop(&worklist);
1258 post_order[
count++] = b;
1264static bool zend_jit_next_is_send_result(
const zend_op *opline)
1269 && (opline+1)->op2_type !=
IS_CONST
1270 && (opline+1)->op1.var == opline->
result.
var) {
1276static bool zend_jit_supported_binary_op(uint8_t op, uint32_t op1_info, uint32_t op2_info)
1313 void *checkpoint =
NULL;
1314 bool recv_emitted = 0;
1315 uint8_t smart_branch_opcode;
1316 uint32_t target_label, target_label2;
1317 uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info, op1_mem_info;
1318 zend_jit_addr op1_addr, op1_def_addr, op2_addr, op2_def_addr, res_addr;
1320 bool ce_is_instanceof;
1325 if (
JIT_G(bisect_limit)) {
1327 if (jit_bisect_pos >=
JIT_G(bisect_limit)) {
1328 if (jit_bisect_pos ==
JIT_G(bisect_limit)) {
1329 fprintf(stderr,
"Not JITing %s%s%s in %s:%d and after due to jit_bisect_limit\n",
1331 op_array->
scope ?
"::" :
"",
1349 zend_jit_start(&ctx, op_array, ssa);
1351 checkpoint = zend_arena_checkpoint(
CG(
arena));
1352 zend_jit_allocate_registers(&ctx, op_array, ssa);
1358 int n = zend_jit_compute_post_order(&ssa->
cfg, 0, sorted_blocks);
1361 b = sorted_blocks[--
n];
1372 zend_jit_recv_entry(&ctx, b);
1375 if (opline != op_array->
opcodes && recv_emitted) {
1376 zend_jit_recv_entry(&ctx, b);
1383 zend_jit_bb_start(&ctx, b);
1384 zend_jit_bb_end(&ctx, b);
1386 }
else if (recv_emitted) {
1387 zend_jit_recv_entry(&ctx, b);
1393 zend_jit_recv_entry(&ctx, b);
1398 zend_jit_free_ctx(&ctx);
1401 zend_arena_release(&
CG(
arena), checkpoint);
1410 zend_jit_free_ctx(&ctx);
1413 zend_arena_release(&
CG(
arena), checkpoint);
1419 zend_jit_bb_start(&ctx, b);
1430 zend_jit_gen_pi(jit, phi);
1432 zend_jit_gen_phi(jit, phi);
1442 zend_jit_osr_entry(&ctx, b);
1452 zend_jit_reset_last_valid_opline(&ctx);
1457 zend_jit_reset_last_valid_opline(&ctx);
1459 zend_jit_reset_last_valid_opline(&ctx);
1467 zend_jit_bb_end(&ctx, b);
1497 opline = op_array->
opcodes + i;
1498 if (zend_jit_inc_call_level(opline->
opcode)) {
1503 switch (opline->
opcode) {
1538 if (!zend_jit_inc_dec(&ctx, opline,
1541 res_use_info, res_info,
1554 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1566 && zend_jit_next_is_send_result(opline)) {
1570 if (!zend_jit_reuse_ip(&ctx)) {
1589 if (!zend_jit_long_math(&ctx, opline,
1592 res_use_info,
RES_INFO(), res_addr,
1601 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1620 && zend_jit_next_is_send_result(opline)) {
1624 if (!zend_jit_reuse_ip(&ctx)) {
1651 if (!zend_jit_math(&ctx, opline,
1654 res_use_info, res_info, res_addr,
1663 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1677 && zend_jit_next_is_send_result(opline)) {
1680 if (!zend_jit_reuse_ip(&ctx)) {
1684 if (!zend_jit_concat(&ctx, opline,
1685 op1_info, op2_info, res_addr,
1694 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1699 if (!zend_jit_supported_binary_op(
1708 op1_mem_info = op1_info;
1711 if (!zend_jit_assign_op(&ctx, opline,
1712 op1_info, op1_addr, OP1_RANGE(),
1724 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1727 if (!zend_jit_supported_binary_op(
1731 if (!zend_jit_assign_dim_op(&ctx, opline,
1744 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1747 if (!zend_jit_assign_dim(&ctx, opline,
1768 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1772 ce_is_instanceof = 0;
1776 ce = op_array->
scope;
1800 if (!zend_jit_incdec_obj(&ctx, opline, op_array, ssa, ssa_op,
1815 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1818 if (!zend_jit_supported_binary_op(
1823 ce_is_instanceof = 0;
1827 ce = op_array->
scope;
1851 if (!zend_jit_assign_obj_op(&ctx, opline, op_array, ssa, ssa_op,
1863 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1867 ce_is_instanceof = 0;
1871 ce = op_array->
scope;
1895 if (!zend_jit_assign_obj(&ctx, opline, op_array, ssa, ssa_op,
1907 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
1916 op2_def_addr = op2_addr;
1930 && zend_jit_next_is_send_result(opline)
1934 if (!zend_jit_reuse_ip(&ctx)) {
1939 if (!zend_jit_assign(&ctx, opline,
1942 OP2_INFO(), op2_addr, op2_def_addr,
1956 op1_def_addr = op1_addr;
1958 if (!zend_jit_qm_assign(&ctx, opline,
1959 OP1_INFO(), op1_addr, op1_def_addr,
1967 if (!zend_jit_init_fcall(&ctx, opline, b, op_array, ssa, ssa_op, call_level,
NULL, 0)) {
1981 if (!zend_jit_send_val(&ctx, opline,
1991 if (!zend_jit_send_ref(&ctx, opline, op_array,
2016 op1_def_addr = op1_addr;
2018 if (!zend_jit_send_var(&ctx, opline, op_array,
2019 OP1_INFO(), op1_addr, op1_def_addr)) {
2031 if (!zend_jit_check_func_arg(&ctx, opline)) {
2036 if (!zend_jit_check_undef_args(&ctx, opline)) {
2045 if (!zend_jit_do_fcall(&ctx, opline, op_array, ssa, call_level, b + 1,
NULL)) {
2062 && (opline+1)->op1.var == opline->
result.
var) {
2064 smart_branch_opcode = (opline+1)->opcode;
2070 res_addr =
OP_REG_ADDR(opline + 1, ssa_op + 1, result_type,
result, result_def);
2073 smart_branch_opcode = 0;
2074 target_label = target_label2 = (uint32_t)-1;
2076 if (!zend_jit_cmp(&ctx, opline,
2081 smart_branch_opcode, target_label, target_label2,
2098 && (opline+1)->op1.var == opline->
result.
var) {
2100 smart_branch_opcode = (opline+1)->opcode;
2106 res_addr =
OP_REG_ADDR(opline + 1, ssa_op + 1, result_type,
result, result_def);
2109 smart_branch_opcode = 0;
2110 target_label = target_label2 = (uint32_t)-1;
2112 if (!zend_jit_identical(&ctx, opline,
2117 smart_branch_opcode, target_label, target_label2,
2128 && (opline+1)->op1.var == opline->
result.
var) {
2130 smart_branch_opcode = (opline+1)->opcode;
2134 smart_branch_opcode = 0;
2135 target_label = target_label2 = (uint32_t)-1;
2137 if (!zend_jit_defined(&ctx, opline, smart_branch_opcode, target_label, target_label2,
NULL)) {
2151 && (opline+1)->op1.var == opline->
result.
var) {
2153 smart_branch_opcode = (opline+1)->opcode;
2157 smart_branch_opcode = 0;
2158 target_label = target_label2 = (uint32_t)-1;
2160 if (!zend_jit_type_check(&ctx, opline,
OP1_INFO(), smart_branch_opcode, target_label, target_label2,
NULL)) {
2166 if ((PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info))
2172 if (!zend_jit_tail_handler(&ctx, opline)) {
2176 if (!zend_jit_return(&ctx, opline, op_array,
2184 if (!zend_jit_bool_jmpznz(&ctx, opline,
2210 if (!zend_jit_bool_jmpznz(&ctx, opline,
2228 && (opline+1)->op1.var == opline->
result.
var) {
2230 smart_branch_opcode = (opline+1)->opcode;
2234 smart_branch_opcode = 0;
2235 target_label = target_label2 = (uint32_t)-1;
2237 if (!zend_jit_isset_isempty_cv(&ctx, opline,
2239 smart_branch_opcode, target_label, target_label2,
2257 && (opline+1)->op1.var == opline->
result.
var) {
2259 smart_branch_opcode = (opline+1)->opcode;
2263 smart_branch_opcode = 0;
2264 target_label = target_label2 = (uint32_t)-1;
2266 if (!zend_jit_in_array(&ctx, opline,
2268 smart_branch_opcode, target_label, target_label2,
2276 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
2279 if (!zend_jit_fetch_dim_read(&ctx, opline, ssa, ssa_op,
2290 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
2296 if (!zend_jit_fetch_dim(&ctx, opline,
2309 if (PROFITABILITY_CHECKS && (!ssa->
ops || !ssa->
var_info)) {
2317 && (opline+1)->op1.var == opline->
result.
var) {
2319 smart_branch_opcode = (opline+1)->opcode;
2323 smart_branch_opcode = 0;
2324 target_label = target_label2 = (uint32_t)-1;
2326 if (!zend_jit_isset_isempty_dim(&ctx, opline,
2330 smart_branch_opcode, target_label, target_label2,
2339 ce_is_instanceof = 0;
2344 ce = op_array->
scope;
2372 if (!zend_jit_fetch_obj(&ctx, opline, op_array, ssa, ssa_op,
2373 op1_info, op1_addr, 0, ce, ce_is_instanceof, on_this, 0, 0,
NULL,
2385 if (!zend_jit_bind_global(&ctx, opline, op1_info)) {
2390 if (!zend_jit_recv(&ctx, opline, op_array)) {
2395 if (!zend_jit_recv_init(&ctx, opline, op_array,
2403 if (!zend_jit_free(&ctx, opline,
OP1_INFO(),
2413 if (!zend_jit_echo(&ctx, opline, op1_info)) {
2436 if (!zend_jit_fetch_this(&ctx, opline, op_array, 0)) {
2443 if (!zend_jit_switch(&ctx, opline, op_array, ssa,
NULL,
NULL)) {
2464 if (!zend_jit_verify_return_type(&ctx, opline, op_array,
OP1_INFO())) {
2473 if (!zend_jit_fe_reset(&ctx, opline, op1_info)) {
2482 if (!zend_jit_fe_fetch(&ctx, opline, op1_info,
OP2_INFO(),
2488 if (!zend_jit_fetch_constant(&ctx, opline, op_array, ssa, ssa_op,
RES_REG_ADDR())) {
2493 if (!zend_jit_jmp_frameless(&ctx, opline,
NULL, 0)) {
2503 ce_is_instanceof = 0;
2508 ce = op_array->
scope;
2531 if (!zend_jit_init_method_call(&ctx, opline, b, op_array, ssa, ssa_op, call_level,
2532 op1_info, op1_addr, ce, ce_is_instanceof, on_this, 0,
NULL,
2546 if (!zend_jit_rope(&ctx, opline, op2_info)) {
2551 jit_frameless_icall0(jit, opline);
2555 jit_frameless_icall1(jit, opline, op1_info);
2560 jit_frameless_icall2(jit, opline, op1_info, op2_info);
2565 jit_frameless_icall3(jit, opline, op1_info, op2_info,
OP1_DATA_INFO());
2572 switch (opline->
opcode) {
2575 if (opline == op_array->
opcodes ||
2578 if (!zend_jit_handler(&ctx, opline,
2583 zend_jit_set_last_valid_opline(&ctx, opline+1);
2593 if (!zend_jit_tail_handler(&ctx, opline)) {
2601 if (!zend_jit_set_ip(&ctx, target)) {
2619 if (!zend_jit_tail_handler(&ctx, opline)) {
2628 for (; i <
end; i++) {
2629 opline = op_array->
opcodes + i;
2630 if (zend_jit_inc_call_level(opline->
opcode)) {
2632 }
else if (zend_jit_dec_call_level(opline->
opcode)) {
2643 if (!zend_jit_call(&ctx, opline, b + 1)) {
2670 if (!zend_jit_handler(&ctx, opline,
2677 if (!zend_jit_handler(&ctx, opline, 1)) {
2703 const zend_op *next_opline = opline + 1;
2706 zend_jit_constructor(&ctx, next_opline, op_array, ssa, call_level, b + 1);
2714 if (!zend_jit_handler(&ctx, opline,
2723 ce = op_array->
scope;
2731 ir_ref if_hook_enter =
ir_IF(jit_CMP_IP(jit, IR_EQ, opline + 1));
2733 if (GCC_GLOBAL_REGS) {
2744 if (!zend_jit_handler(&ctx, opline,
2751 if (!zend_jit_set_cond(&ctx, opline + 2, opline->
result.
var)) {
2757 if (zend_jit_dec_call_level(opline->
opcode)) {
2761 zend_jit_bb_end(&ctx, b);
2765 zend_jit_common_return(jit);
2767 bool left_frame = 0;
2770 if (!zend_jit_free_cvs(&ctx)) {
2779 uint32_t info = zend_ssa_cv_info(op_array, ssa,
j);
2784 if (!zend_jit_leave_frame(&ctx)) {
2788 if (!zend_jit_free_cv(&ctx, info,
j)) {
2794 if (!zend_jit_leave_func(&ctx, op_array,
NULL,
MAY_BE_ANY, left_frame,
2800 handler = zend_jit_finish(&ctx);
2804 zend_jit_free_ctx(&ctx);
2807 zend_arena_release(&
CG(
arena), checkpoint);
2812 zend_jit_free_ctx(&ctx);
2814 zend_arena_release(&
CG(
arena), checkpoint);
2834static void zend_jit_cleanup_func_info(
zend_op_array *op_array)
2840 caller_info = func_info->caller_info;
2841 callee_info = func_info->callee_info;
2856 while (caller_info) {
2862 while (callee_info) {
2876 uint8_t orig_trigger;
2878 if (*dasm_ptr == dasm_end) {
2882 orig_trigger =
JIT_G(trigger);
2883 JIT_G(trigger) = trigger;
2884 checkpoint = zend_arena_checkpoint(
CG(
arena));
2901 if (zend_jit_op_array_analyze1(op_array, script, &ssa) !=
SUCCESS) {
2906 zend_jit_collect_calls(op_array, script);
2914 if (zend_jit_op_array_analyze2(op_array, script, &ssa,
ZCG(accel_directives).optimization_level) !=
SUCCESS) {
2922 if (zend_jit(op_array, &ssa, rt_opline) !=
SUCCESS) {
2926 zend_jit_cleanup_func_info(op_array);
2927 zend_arena_release(&
CG(
arena), checkpoint);
2928 JIT_G(trigger) = orig_trigger;
2932 zend_jit_cleanup_func_info(op_array);
2933 zend_arena_release(&
CG(
arena), checkpoint);
2934 JIT_G(trigger) = orig_trigger;
2945 bool do_bailout = 0;
2984void zend_jit_check_funcs(
HashTable *function_table,
bool is_method) {
2995 op_array = &
func->op_array;
3002 if (opline->
handler == zend_jit_profile_jit_handler) {
3022 bool do_bailout = 0;
3027 if (jit_extension) {
3032 for (i = 0; i < op_array->
last; i++) {
3036#ifdef HAVE_GCC_GLOBAL_REGS
3037 EX(opline) = opline;
3060 if (
JIT_G(hot_func)) {
3069 opline->
handler = (
const void*)zend_jit_func_hot_counter_handler;
3072 if (
JIT_G(hot_loop)) {
3079 (
const void*)zend_jit_loop_hot_counter_handler;
3085static int zend_jit_restart_hot_counters(
zend_op_array *op_array)
3092 for (i = 0; i < op_array->
last; i++) {
3096 if (zend_jit_build_cfg(op_array, &cfg) !=
SUCCESS) {
3100 zend_jit_setup_hot_counters_ex(op_array, &cfg);
3105static int zend_jit_setup_hot_counters(
zend_op_array *op_array)
3114 if (zend_jit_build_cfg(op_array, &cfg) !=
SUCCESS) {
3119 if (!jit_extension) {
3124 jit_extension->
op_array = op_array;
3126 for (i = 0; i < op_array->
last; i++) {
3131 zend_jit_setup_hot_counters_ex(op_array, &cfg);
3142 if (dasm_ptr ==
NULL) {
3152 zend_error(
E_WARNING,
"Preloading is incompatible with first-exec and profile triggered JIT");
3164 if (!jit_extension) {
3169 jit_extension->
op_array = op_array;
3172 opline->
handler = (
const void*)zend_jit_runtime_jit_handler;
3182 zend_error(
E_WARNING,
"Preloading is incompatible with first-exec and profile triggered JIT");
3194 if (!jit_extension) {
3199 jit_extension->
op_array = op_array;
3202 opline->
handler = (
const void*)zend_jit_profile_jit_handler;
3208 return zend_jit_setup_hot_counters(op_array);
3210 return zend_jit_setup_hot_trace_counters(op_array);
3226 if (dasm_ptr ==
NULL || *dasm_ptr == dasm_end) {
3230 checkpoint = zend_arena_checkpoint(
CG(
arena));
3271 if (zend_jit_op_array_analyze2(call_graph.
op_arrays[i], script, &info->
ssa,
ZCG(accel_directives).optimization_level) !=
SUCCESS) {
3297 zend_arena_release(&
CG(
arena), checkpoint);
3311 if (jit_extension) {
3327 zend_arena_release(&
CG(
arena), checkpoint);
3337#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3338 if (zend_write_protect) {
3339 pthread_jit_write_protect_np(0);
3344 if (
mprotect(dasm_buf, dasm_size, opts) != 0) {
3348#elif defined(_WIN32)
3352 new = PAGE_EXECUTE_READWRITE;
3354 new = PAGE_READWRITE;
3356 if (!VirtualProtect(dasm_buf, dasm_size,
new, &old)) {
3359 fprintf(stderr,
"VirtualProtect() failed [%u] %s\n",
err,
msg);
3370#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3371 if (zend_write_protect) {
3372 pthread_jit_write_protect_np(1);
3379#elif defined(_WIN32)
3383 if (!VirtualProtect(dasm_buf, dasm_size, PAGE_EXECUTE_READ, &old)) {
3386 fprintf(stderr,
"VirtualProtect() failed [%u] %s\n",
err,
msg);
3393static void zend_jit_init_handlers(
void)
3396 zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
3397 zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
3398 zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
3399 zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
3400 zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
3401 zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
3402 zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
3404 zend_jit_runtime_jit_handler = (
const void*)zend_runtime_jit;
3417 zend_jit_trace_init_caches();
3427static int zend_jit_parse_config_num(
zend_long jit)
3436 if (jit % 10 == 0 || jit % 10 > 5)
return FAILURE;
3437 JIT_G(opt_level) = jit % 10;
3440 if (jit % 10 > 5 || jit % 10 == 4)
return FAILURE;
3441 JIT_G(trigger) = jit % 10;
3444 if (jit % 10 > 2)
return FAILURE;
3445 JIT_G(opt_flags) = jit % 10;
3448 if (jit % 10 > 1)
return FAILURE;
3451 if (jit / 10 != 0)
return FAILURE;
3508 zend_error(
E_WARNING,
"Invalid \"opcache.jit\" setting. Should be \"disable\", \"on\", \"off\", \"tracing\", \"function\" or 4-digit number");
3530 jit_globals_id = ts_allocate_id(&jit_globals_id,
sizeof(
zend_jit_globals), (ts_allocate_ctor) zend_jit_globals_ctor, (ts_allocate_dtor) zend_jit_globals_dtor);
3553 zend_error(
E_WARNING,
"JIT is incompatible with third party extensions that override zend_execute_ex(). JIT disabled.");
3560 for (i = 0; i <= 256; i++) {
3568 zend_error(
E_WARNING,
"JIT is incompatible with third party extensions that setup user opcode handlers. JIT disabled.");
3576#if defined(IR_TARGET_AARCH64)
3577 if (
JIT_G(buffer_size) > 128*1024*1024) {
3578 zend_error(
E_WARNING,
"JIT on AArch64 doesn't support opcache.jit_buffer_size above 128M.");
3583#elif defined(IR_TARGET_X64)
3584 if (
JIT_G(buffer_size) > 2 *
Z_L(1024*1024*1024)) {
3600#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3601 zend_write_protect = pthread_jit_write_protect_supported_np();
3606 dasm_ptr = dasm_end = (
void*)(((
char*)dasm_buf) +
size -
sizeof(*dasm_ptr) * 2);
3609#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
3610 if (zend_write_protect) {
3611 pthread_jit_write_protect_np(1);
3623#elif defined(_WIN32)
3627 if (!VirtualProtect(dasm_buf, dasm_size, PAGE_EXECUTE_READWRITE, &old)) {
3630 fprintf(stderr,
"VirtualProtect() failed [%u] %s\n",
err,
msg);
3636 if (!VirtualProtect(dasm_buf, dasm_size, PAGE_EXECUTE_READ, &old)) {
3639 fprintf(stderr,
"VirtualProtect() failed [%u] %s\n",
err,
msg);
3647 *dasm_ptr = dasm_buf;
3649 zend_jit_stub_handlers = dasm_buf;
3650 *dasm_ptr = (
void**)*dasm_ptr +
sizeof(zend_jit_stubs) /
sizeof(zend_jit_stubs[0]);
3651#elif defined(IR_TARGET_AARCH64)
3652 zend_jit_stub_handlers = dasm_buf;
3653 *dasm_ptr = (
void**)*dasm_ptr + (
sizeof(zend_jit_stubs) /
sizeof(zend_jit_stubs[0])) * 2;
3654 memset(zend_jit_stub_handlers, 0, (
sizeof(zend_jit_stubs) /
sizeof(zend_jit_stubs[0])) * 2 *
sizeof(
void*));
3659#if defined(_WIN32) || defined(IR_TARGET_AARCH64)
3660 zend_jit_stub_handlers = dasm_buf;
3661 zend_jit_init_handlers();
3666 zend_jit_setup(reattached);
3669 zend_jit_init_handlers();
3672 zend_jit_trace_startup(reattached);
3676 dasm_ptr[1] = dasm_ptr[0];
3683 fprintf(stderr,
"\nJIT memory usage: %td\n", (
ptrdiff_t)((
char*)*dasm_ptr - (
char*)dasm_buf));
3686 zend_jit_shutdown_ir();
3689 ts_free_id(jit_globals_id);
3695static void zend_jit_reset_counters(
void)
3716 zend_jit_reset_counters();
3718 zend_jit_reset_counters();
3719 zend_jit_trace_reset_caches();
3733 zend_jit_check_funcs(
EG(function_table), 0);
3749static void zend_jit_restart_preloaded_op_array(
zend_op_array *op_array)
3758 zend_jit_restart_hot_trace_counters(op_array);
3760 zend_jit_restart_hot_counters(op_array);
3774 opline->
handler = (
const void*)zend_jit_runtime_jit_handler;
3776 opline->
handler = (
const void*)zend_jit_profile_jit_handler;
3795 zend_jit_restart_preloaded_op_array(op_array);
3801 zend_jit_restart_preloaded_op_array(op_array);
3813 dasm_ptr[0] = dasm_ptr[1];
3815 zend_jit_trace_restart();
3817 if (
ZCSG(preload_script)) {
3818 zend_jit_restart_preloaded_script(
ZCSG(preload_script));
3819 if (
ZCSG(saved_scripts)) {
3823 zend_jit_restart_preloaded_script(*
p);
SAPI_API sapi_module_struct sapi_module
#define ACCELERATOR_PRODUCT_NAME
struct _zend_persistent_script zend_persistent_script
fprintf($stream, string $format, mixed ... $values)
count(Countable|array $value, int $mode=COUNT_NORMAL)
memset(ptr, 0, type->size)
zend_ffi_ctype_name_buf buf
#define ir_IF(_condition)
#define ir_TAILCALL(type, func)
#define ir_CONST_I32(_val)
unsigned const char * end
#define offsetof(STRUCTURE, FIELD)
unsigned char key[REFLECTION_KEY_LEN]
int mprotect(void *addr, size_t size, int protection)
zend_op_array ** op_arrays
zend_op_array * caller_op_array
zend_call_info * next_caller
zend_function * callee_func
zend_call_info * next_callee
zend_basic_block * blocks
zend_object *(* create_object)(zend_class_entry *class_type)
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@166057154351252324007362117353350250255142166322 user
uint32_t num_hooked_props
HashTable properties_info
union _zend_class_entry::@126215362204241324314155352336150042254204116267 info
zend_function * constructor
zend_class_entry * parent
zend_ssa_var_info return_info
zend_call_info ** call_map
const void * orig_handler
const zend_op_array * op_array
const void * orig_handlers[1]
const zend_op_array * op_array
zend_op_array ** dynamic_func_defs
zend_live_range * live_range
zend_string * function_name
uint32_t num_dynamic_func_defs
zend_op_array main_op_array
zend_ssa_phi * definition_phi
zend_ssa_phi * phi_use_chain
zend_ssa_var_info * var_info
PHP_WINUTIL_API char * php_win32_error_to_msg(HRESULT error)
PHP_WINUTIL_API void php_win32_error_msg_free(char *msg)
ZEND_API bool zend_dtrace_enabled
ZEND_API ZEND_COLD void zend_error(int type, const char *format,...)
#define ZEND_MM_ALIGNED_SIZE_EX(size, alignment)
strcmp(string $string1, string $string2)
ZEND_API zend_call_info ** zend_build_call_map(zend_arena **arena, zend_func_info *info, const zend_op_array *op_array)
ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32_t build_flags, zend_op_array *op_array, zend_func_info *func_info)
ZEND_API void zend_build_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph)
ZEND_API void zend_analyze_call_graph(zend_arena **arena, zend_script *script, zend_call_graph *call_graph)
struct _zend_call_graph zend_call_graph
ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg)
ZEND_API void zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg)
ZEND_API void zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg)
ZEND_API void zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg)
struct _zend_basic_block zend_basic_block
#define ZEND_CFG_RECV_ENTRY
#define ZEND_BB_FINALLY_END
#define ZEND_BB_REACHABLE
#define ZEND_CFG_NO_ENTRY_PREDECESSORS
struct _zend_cfg zend_cfg
#define ZEND_CFG_STACKLESS
#define ZEND_SSA_RC_INFERENCE
#define ZEND_BB_LOOP_HEADER
#define ZEND_BB_RECV_ENTRY
#define ZEND_SSA_USE_CV_RESULTS
#define ZEND_ACC_IMMUTABLE
#define ZEND_COMPILE_PRELOAD
#define ZEND_ACC_HAS_TYPE_HINTS
#define IS_SMART_BRANCH_JMPNZ
#define ZEND_INTERNAL_FUNCTION
#define ZEND_ACC_TRAIT_CLONE
#define RUN_TIME_CACHE(op_array)
#define IS_SMART_BRANCH_JMPZ
#define ZEND_USER_FUNCTION
#define ZEND_ACC_GENERATOR
struct _zend_op_array zend_op_array
struct _zend_property_info zend_property_info
#define RT_CONSTANT(opline, node)
#define ZEND_ACC_HAS_RETURN_TYPE
struct _zend_arg_info zend_arg_info
#define OP_JMP_ADDR(opline, node)
struct _zend_live_range zend_live_range
#define ZEND_INTERNAL_CLASS
#define IS_CONSTANT_UNQUALIFIED_IN_NAMESPACE
#define ZEND_ACC_RETURN_REFERENCE
#define ZEND_ACC_PROTECTED
#define ZEND_CONSTANT_FLAGS(c)
struct _zend_constant zend_constant
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num)
ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data)
#define ZEND_DUMP_HIDE_UNREACHABLE
#define ZEND_DUMP_RC_INFERENCE
ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
ZEND_API void(* zend_execute_ex)(zend_execute_data *execute_data)
ZEND_API void execute_ex(zend_execute_data *execute_data)
ZEND_API int zend_get_op_array_extension_handle(const char *module_name)
union _zend_function zend_function
#define ZEND_FUNC_JIT_ON_PROF_REQUEST
#define ZEND_FUNC_JIT_ON_HOT_TRACE
struct _zend_call_info zend_call_info
#define ZEND_FUNC_INDIRECT_VAR_ACCESS
#define ZEND_FUNC_INFO(op_array)
struct _zend_func_info zend_func_info
#define ZEND_FUNC_JIT_ON_HOT_COUNTERS
#define ZEND_SET_FUNC_INFO(op_array, info)
#define ZEND_FUNC_IRREDUCIBLE
#define ZEND_FUNC_JIT_ON_FIRST_EXEC
ZEND_API zval *ZEND_FASTCALL zend_hash_find_known_hash(const HashTable *ht, const zend_string *key)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_MAP_REVERSE_FOREACH_PTR(ht, _ptr)
#define ZEND_HASH_FOREACH_END()
ZEND_API void zend_init_func_return_info(const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret)
ZEND_API bool zend_may_throw(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, const zend_ssa *ssa)
ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, zend_ssa *ssa)
ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa)
ZEND_API zend_result zend_ssa_inference(zend_arena **arena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level)
#define ZEND_INI_STAGE_STARTUP
#define ZEND_INI_STAGE_RUNTIME
#define ZEND_JIT_LEVEL_INLINE
struct _zend_jit_globals zend_jit_globals
#define ZEND_JIT_DEBUG_PERF_DUMP
#define ZEND_JIT_LEVEL_OPT_SCRIPT
struct _zend_jit_trace_rec zend_jit_trace_rec
int zend_jit_script(zend_script *script)
void zend_jit_unprotect(void)
zend_jit_globals jit_globals
#define ZEND_JIT_ON_FIRST_EXEC
int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage)
void zend_jit_activate(void)
#define ZEND_JIT_LEVEL_OPT_FUNC
#define ZEND_JIT_ON_HOT_COUNTERS
#define ZEND_JIT_DEBUG_PERSISTENT
void zend_jit_protect(void)
#define ZEND_JIT_COUNTER_INIT
#define ZEND_JIT_REG_ALLOC_LOCAL
void zend_jit_deactivate(void)
#define ZEND_JIT_ON_SCRIPT_LOAD
#define ZEND_JIT_ON_PROF_REQUEST
#define ZEND_JIT_ON_HOT_TRACE
#define ZEND_JIT_LEVEL_OPT_FUNCS
int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
void zend_jit_shutdown(void)
#define ZEND_JIT_DEBUG_GDB
int zend_jit_check_support(void)
#define ZEND_JIT_REG_ALLOC_GLOBAL
int zend_jit_config(zend_string *jit_options, int stage)
#define ZEND_JIT_DEBUG_REG_ALLOC
void zend_jit_restart(void)
#define ZEND_JIT_DEBUG_SSA
ZEND_EXT_API void zend_jit_status(zval *ret)
void zend_jit_startup(void *jit_buffer, size_t size, bool reattached)
#define ZEND_JIT_DEBUG_SIZE
void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend_op *opline)
#define RES_USE_REG_ADDR()
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS)
zend_ulong zend_jit_profile_counter
#define OP1_DEF_REG_ADDR()
#define TRACE_FRAME_IS_LAST_SEND_BY_VAL(frame)
#define OP1_DATA_DEF_REG_ADDR()
#define ZEND_ADDR_MEM_ZVAL(reg, offset)
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_counter_helper(ZEND_OPCODE_HANDLER_ARGS)
int zend_jit_profile_counter_rid
const zend_op * zend_jit_halt_op
#define ZEND_COUNTER_INFO(op_array)
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HANDLER_ARGS)
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS)
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_HANDLER_ARGS)
#define OP2_DEF_REG_ADDR()
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_func_trace_helper(ZEND_OPCODE_HANDLER_ARGS)
struct _zend_jit_op_array_hot_extension zend_jit_op_array_hot_extension
#define OP1_DATA_REG_ADDR()
#define zend_jit_op_array_hash(op_array)
#define OP_REG_ADDR(opline, ssa_op, type, op, _ssa_op)
#define ZEND_HOT_COUNTERS_COUNT
struct _zend_jit_op_array_extension zend_jit_op_array_extension
int16_t zend_jit_hot_counters[ZEND_HOT_COUNTERS_COUNT]
struct _zend_jit_ctx zend_jit_ctx
struct _zend_jit_reg_var zend_jit_reg_var
#define ZEND_STRTOL(s0, s1, base)
struct _zend_string zend_string
#define IS_VALID_PROPERTY_OFFSET(offset)
ZEND_API bool ZEND_FASTCALL instanceof_function_slow(const zend_class_entry *instance_ce, const zend_class_entry *ce)
struct _zend_script zend_script
#define ZEND_OPTIMIZER_NARROW_TO_DOUBLE
#define ALLOCA_FLAG(name)
#define ZEND_UNREACHABLE()
#define EMPTY_SWITCH_DEFAULT_CASE()
struct _zend_class_entry zend_class_entry
void zend_shared_alloc_lock(void)
void * zend_shared_alloc_get_xlat_entry(const void *key_pointer)
void zend_shared_alloc_unlock(void)
void zend_shared_alloc_register_xlat_entry(const void *key_pointer, const void *value)
void * zend_shared_alloc(size_t size)
ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa)
ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa)
struct _zend_ssa_range zend_ssa_range
struct _zend_ssa zend_ssa
struct _zend_ssa_phi zend_ssa_phi
struct _zend_ssa_op zend_ssa_op
struct _zend_ssa_var_info zend_ssa_var_info
#define zend_string_equals_ci(s1, s2)
#define zend_string_equals_literal_ci(str, c)
#define MAY_BE_ARRAY_OF_ANY
#define MAY_BE_ARRAY_OF_REF
#define MAY_BE_ARRAY_KEY_ANY
#define ZEND_TYPE_PURE_MASK(t)
#define Z_STRVAL_P(zval_p)
struct _zend_array HashTable
#define ZEND_TYPE_IS_ONLY_MASK(t)
#define ZEND_TYPE_IS_SET(t)
struct _zend_execute_data zend_execute_data
ZEND_API int zend_vm_kind(void)
ZEND_API const zend_op * zend_get_halt_op(void)
fbc internal_function handler(call, ret)
#define ZEND_IS_IDENTICAL
#define ZEND_DECLARE_ANON_CLASS
#define ZEND_FETCH_CONSTANT
#define ZEND_ASSIGN_DIM_OP
#define ZEND_ISSET_ISEMPTY_CV
#define ZEND_VERIFY_RETURN_TYPE
#define ZEND_FETCH_LIST_R
#define ZEND_INCLUDE_OR_EVAL
#define ZEND_GENERATOR_CREATE
#define ZEND_INIT_USER_CALL
#define ZEND_FRAMELESS_ICALL_0
#define ZEND_FETCH_LIST_W
#define ZEND_CALLABLE_CONVERT
#define ZEND_ASSERT_CHECK
#define ZEND_RETURN_BY_REF
#define ZEND_SWITCH_STRING
#define ZEND_FETCH_OBJ_FUNC_ARG
#define ZEND_FETCH_DIM_FUNC_ARG
#define ZEND_FRAMELESS_ICALL_1
#define ZEND_IS_NOT_EQUAL
#define ZEND_IS_NOT_IDENTICAL
#define ZEND_FETCH_OBJ_IS
#define ZEND_POST_DEC_OBJ
#define ZEND_CHECK_FUNC_ARG
#define ZEND_VM_KIND_HYBRID
#define ZEND_FRAMELESS_ICALL_3
#define ZEND_INIT_NS_FCALL_BY_NAME
#define ZEND_IS_SMALLER_OR_EQUAL
#define ZEND_INIT_FCALL_BY_NAME
#define ZEND_FRAMELESS_ICALL_2
#define ZEND_SEND_VAR_NO_REF_EX
#define ZEND_SEND_FUNC_ARG
#define ZEND_CHECK_UNDEF_ARGS
#define ZEND_ISSET_ISEMPTY_DIM_OBJ
#define ZEND_BIND_INIT_STATIC_OR_JMP
#define ZEND_GENERATOR_RETURN
#define ZEND_BEGIN_SILENCE
#define ZEND_JMP_FRAMELESS
#define ZEND_INIT_DYNAMIC_CALL
#define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
#define ZEND_ASSIGN_OBJ_OP
#define ZEND_FETCH_DIM_IS
#define ZEND_VERIFY_NEVER_TYPE
#define ZEND_SEND_VAR_NO_REF
#define ZEND_POST_INC_OBJ
#define ZEND_DO_FCALL_BY_NAME
#define ZEND_INIT_METHOD_CALL
#define ZEND_INIT_STATIC_METHOD_CALL
#define ZEND_FETCH_DIM_RW
#define ZEND_VM_KIND_CALL
#define ZEND_WORKLIST_ALLOCA(w, _len, use_heap)
struct _zend_worklist zend_worklist
#define ZEND_WORKLIST_FREE_ALLOCA(w, use_heap)