35#ifndef ZEND_OPTIMIZER_MAX_REGISTERED_PASSES
36# define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES 32
193 }
else if (ini_entry->
value) {
246 zend_string_hash_val(str);
250static inline void drop_leading_backslash(
zval *
val) {
253 zval_ptr_dtor_nogc(
val);
258static inline uint32_t alloc_cache_slots(
zend_op_array *op_array, uint32_t num) {
264#define REQUIRES_STRING(val) do { \
265 if (Z_TYPE_P(val) != IS_STRING) { \
270#define TO_STRING_NOWARN(val) do { \
271 if (Z_TYPE_P(val) >= IS_ARRAY) { \
274 convert_to_string(val); \
283 switch ((opline-1)->opcode) {
293 zval_ptr_dtor_nogc(
val);
312 drop_leading_backslash(
val);
315 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
319 drop_leading_backslash(
val);
322 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
326 drop_leading_backslash(
val);
328 opline->
op2.
num = alloc_cache_slots(op_array, 1);
329 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
333 drop_leading_backslash(
val);
336 opline->
result.
num = alloc_cache_slots(op_array, 1);
338 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
342 drop_leading_backslash(
val);
347 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
399 zval_ptr_dtor_nogc(
val);
451 drop_leading_backslash(
val);
453 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
458 drop_leading_backslash(
val);
460 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
461 opline->
result.
num = alloc_cache_slots(op_array, 1);
479 drop_leading_backslash(
val);
481 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
492 zval_ptr_dtor_nogc(
val);
496 opline->
result.
num = alloc_cache_slots(op_array, 1);
511 drop_leading_backslash(
val);
513 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
514 opline->
result.
num = alloc_cache_slots(op_array, 1);
522 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
523 opline->
result.
num = alloc_cache_slots(op_array, 2);
528 zend_optimizer_add_literal_string(op_array, zend_string_tolower(
Z_STR_P(
val)));
530 opline->
result.
num = alloc_cache_slots(op_array, 2);
554 (opline + 1)->extended_value = alloc_cache_slots(op_array, 3);
592 zval_ptr_dtor_nogc(
val);
628 while (opline <
end) {
646 while (opline <
end) {
672 zval_ptr_dtor_nogc(
val);
709 switch (new_opline->
opcode) {
797static bool zend_optimizer_ignore_class(
zval *ce_zv,
zend_string *filename)
803 size_t offset = ce_bucket -
EG(class_table)->arData;
804 if (
offset <
EG(persistent_classes_count)) {
812static bool zend_optimizer_ignore_function(
zval *fbc_zv,
zend_string *filename)
821 size_t offset = fbc_bucket -
EG(function_table)->arData;
822 if (
offset <
EG(persistent_functions_count)) {
826 return !
fbc->op_array.filename ||
fbc->op_array.filename != filename;
841 if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array ? op_array->
filename :
NULL)) {
846 return op_array->
scope;
864 return op_array->
scope;
872 bool is_static_reference =
false;
884 if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array->
filename)) {
894 ce = op_array->
scope;
896 ce = op_array->
scope;
897 is_static_reference =
true;
915 *is_prototype = is_static_reference
934 if (!zend_optimizer_ignore_function(func_zv, op_array->
filename)) {
949 if (!zend_optimizer_ignore_function(func_zv, op_array->
filename)) {
958 script, op_array, opline);
964 bool same_scope =
fbc->common.scope == op_array->
scope;
965 if (is_public || same_scope) {
986 bool same_scope =
fbc->common.scope == op_array->
scope;
987 return same_scope ?
fbc :
NULL;
994 *is_prototype =
true;
1015 *is_prototype =
false;
1025 script, op_array, opline);
1056 uint32_t var = free_opline->
op1.
var;
1057 ZEND_ASSERT(zend_optimizer_is_loop_var_free(free_opline));
1059 while (--free_opline >= op_array->
opcodes) {
1192 end = opline + op_array->
last;
1193 while (opline <
end) {
1204#if !ZEND_USE_ABS_CONST_ADDR
1218#if ZEND_USE_ABS_JMP_ADDR && !ZEND_USE_ABS_CONST_ADDR
1224#if !ZEND_USE_ABS_CONST_ADDR
1242 end = opline + op_array->
last;
1243 while (opline <
end) {
1251 switch (opline->
opcode) {
1252#if ZEND_USE_ABS_JMP_ADDR && !ZEND_USE_ABS_CONST_ADDR
1255 opline->
op1.jmp_addr = &op_array->
opcodes[opline->
op1.jmp_addr - old_opcodes];
1269 opline->
op2.jmp_addr = &op_array->
opcodes[opline->
op2.jmp_addr - old_opcodes];
1273 opline->
op2.jmp_addr = &op_array->
opcodes[opline->
op2.jmp_addr - old_opcodes];
1304 if (opline + 1 <
end) {
1328#if ZEND_USE_ABS_JMP_ADDR && !ZEND_USE_ABS_CONST_ADDR
1334#if !ZEND_USE_ABS_CONST_ADDR
1352 end = opline + op_array->
last;
1353 while (opline <
end) {
1373 switch (opline->
opcode) {
1374#if ZEND_USE_ABS_JMP_ADDR && !ZEND_USE_ABS_CONST_ADDR
1377 opline->
op1.jmp_addr = &op_array->
opcodes[opline->
op1.jmp_addr - old_opcodes];
1391 opline->
op2.jmp_addr = &op_array->
opcodes[opline->
op2.jmp_addr - old_opcodes];
1395 opline->
op2.jmp_addr = &op_array->
opcodes[opline->
op2.jmp_addr - old_opcodes];
1426 if (opline + 1 <
end) {
1440#ifdef ZEND_VERIFY_TYPE_INFERENCE
1471 zend_revert_pass_two(op_array);
1474 zend_optimize(op_array, ctx);
1477 zend_redo_pass_two(op_array);
1490 end = opline + op_array->
last;
1491 while (opline <
end) {
1493 func = zend_hash_find_ptr(
1504static void zend_adjust_fcall_stack_size_graph(
zend_op_array *op_array)
1535 if (func_info->ssa.vars[ssa_var].phi_use_chain) {
1536 ssa_var = func_info->ssa.vars[ssa_var].phi_use_chain->ssa_var;
1539 uint32_t
type = func_info->ssa.var_info[ssa_var].type;
1543static void zend_foreach_op_array_helper(
1559 zend_foreach_op_array_helper(op_array,
func,
context);
1568 if (op_array->
scope == ce
1572 zend_foreach_op_array_helper(op_array,
func,
context);
1583 zend_foreach_op_array_helper(&hooks[i]->op_array,
func,
context);
1603static void zend_optimizer_call_registered_passes(
zend_script *script,
void *ctx) {
1620 ctx.
arena = zend_arena_create(64 * 1024);
1636 zend_revert_pass_two(call_graph.
op_arrays[i]);
1637 zend_optimize(call_graph.
op_arrays[i], &ctx);
1656 func_info->flags = func_info->ssa.cfg.flags;
1706 zend_adjust_fcall_stack_size_graph(call_graph.
op_arrays[i]);
1713 if (func_info && func_info->ssa.var_info) {
1714 zend_redo_pass_two_ex(op_array, &func_info->ssa);
1719 zend_redo_pass_two(op_array);
1748 if (orig_op_array != op_array) {
1749 uint32_t fn_flags = op_array->
fn_flags;
1753 *op_array = *orig_op_array;
1762 zend_optimizer_call_registered_passes(script, &ctx);
1772 zend_arena_destroy(ctx.
arena);
dirname(string $path, int $levels=1)
void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy)
void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx)
void zend_optimizer_compact_vars(zend_op_array *op_array)
void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, zend_call_info **call_map)
zend_result zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa)
void zend_optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx)
#define pass(a, b, c, mul)
void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx)
void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx)
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
unsigned const char * end
zend_op_array ** op_arrays
HashTable constants_table
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@166057154351252324007362117353350250255142166322 user
HashTable properties_info
union _zend_class_entry::@126215362204241324314155352336150042254204116267 info
zend_function * constructor
zend_class_entry * parent
zend_function * prototype
HashTable * static_variables
zend_op_array ** dynamic_func_defs
zend_live_range * live_range
uint32_t num_dynamic_func_defs
zend_long optimization_level
zend_op_array main_op_array
zend_ssa_var_info * var_info
struct _zend_function::@236135173067030250234125302313220025134003177336 common
ZEND_API HashTable module_registry
#define ZVAL_EMPTY_STRING(z)
#define ZEND_MM_ALIGNED_SIZE_EX(size, alignment)
#define erealloc(ptr, size)
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_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
#define CRT_CONSTANT(node)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op)
ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, const zval *op2)
ZEND_API size_t zend_dirname(char *path, size_t len)
#define ZEND_PROPERTY_HOOK_COUNT
zend_result(ZEND_FASTCALL * binary_op_type)(zval *, zval *, zval *)
#define ZEND_FETCH_CLASS_SELF
#define ZEND_FETCH_CLASS_MASK
#define ZEND_SET_OP_JMP_ADDR(opline, node, val)
#define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline, node)
#define IS_SMART_BRANCH_JMPNZ
#define ZEND_INTERNAL_FUNCTION
#define ZEND_ACC_DONE_PASS_TWO
#define ZEND_ACC_ABSTRACT
#define ZEND_OFFSET_TO_OPLINE_NUM(op_array, base, offset)
#define ZEND_CLASS_CONST_FLAGS(c)
#define ZEND_FREE_ON_RETURN
#define ZEND_ACC_TRAIT_CLONE
#define IS_SMART_BRANCH_JMPZ
#define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node)
ZEND_API binary_op_type get_binary_op(int opcode)
#define ZEND_USER_FUNCTION
struct _zend_op_array zend_op_array
struct _zend_class_constant zend_class_constant
struct _zend_property_info zend_property_info
ZEND_API unary_op_type get_unary_op(int opcode)
#define ZEND_ACC_PRELOADED
#define ZEND_FETCH_CLASS_STATIC
#define RT_CONSTANT(opline, node)
#define ZEND_ACC_PPP_MASK
#define ZEND_FETCH_CLASS_PARENT
#define ZEND_ACC_HAS_RETURN_TYPE
struct _zend_arg_info zend_arg_info
#define ZEND_FETCH_OBJ_FLAGS
ZEND_API void zend_recalc_live_ranges(zend_op_array *op_array, zend_needs_live_range_cb needs_live_range)
struct _zend_internal_function zend_internal_function
#define ZEND_ACC_DEPRECATED
zend_result(ZEND_FASTCALL * unary_op_type)(zval *, zval *)
#define ZEND_ACC_RETURN_REFERENCE
#define ZEND_RETURNS_FUNCTION
#define ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline_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_LIVE_RANGES
union _zend_function zend_function
zend_result zend_func_info_startup(void)
zend_result zend_func_info_shutdown(void)
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_SET_FUNC_INFO(op_array, info)
struct _zend_ini_entry zend_ini_entry
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_MAP_FOREACH_VAL(ht, _val)
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define ZEND_HANDLE_NUMERIC(key, idx)
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_FOREACH_VAL(ht, _val)
ZEND_API void zend_init_func_return_info(const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret)
struct _zend_string zend_string
struct _zend_module_entry zend_module_entry
#define MODULE_PERSISTENT
ZEND_API zend_property_info * zend_get_property_info(const zend_class_entry *ce, zend_string *member, int silent)
#define ZEND_WRONG_PROPERTY_INFO
ZEND_API void ZEND_FASTCALL convert_to_array(zval *op)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
const zend_class_constant * zend_fetch_class_const_info(const zend_script *script, const zend_op_array *op_array, const zend_op *opline, bool *is_prototype)
bool zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval *value)
zend_class_entry * zend_optimizer_get_class_entry_from_op1(const zend_script *script, const zend_op_array *op_array, const zend_op *opline)
zend_class_entry * zend_optimizer_get_class_entry(const zend_script *script, const zend_op_array *op_array, zend_string *lcname)
void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval *value)
uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args)
bool zend_optimizer_update_op1_const(zend_op_array *op_array, zend_op *opline, zval *val)
zend_op * zend_optimizer_get_loop_var_def(const zend_op_array *op_array, zend_op *free_opline)
zend_result zend_optimizer_eval_strlen(zval *result, const zval *op1)
int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv)
zend_result zend_optimizer_eval_binary_op(zval *result, uint8_t opcode, zval *op1, zval *op2)
#define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES
zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1)
struct @255111274001026031333362231262011242214112107366 zend_optimizer_registered_passes
ZEND_API void zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
zend_result zend_optimizer_eval_special_func_call(zval *result, zend_string *name, zend_string *arg)
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context)
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline)
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist)
zend_result zend_optimizer_startup(void)
void zend_optimizer_convert_to_free_op1(zend_op_array *op_array, zend_op *opline)
#define REQUIRES_STRING(val)
zend_result zend_optimizer_shutdown(void)
zend_result zend_optimizer_eval_unary_op(zval *result, uint8_t opcode, zval *op1)
ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass)
bool zend_optimizer_update_op2_const(zend_op_array *op_array, zend_op *opline, zval *val)
bool zend_optimizer_replace_by_const(zend_op_array *op_array, zend_op *opline, uint8_t type, uint32_t var, zval *val)
ZEND_API void zend_optimizer_unregister_pass(int idx)
#define TO_STRING_NOWARN(val)
zend_function * zend_optimizer_get_called_func(zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype)
struct _zend_script zend_script
void(* zend_optimizer_pass_t)(zend_script *, void *context)
#define ZEND_OPTIMIZER_PASS_9
#define ZEND_DUMP_AFTER_PASS_4
#define ZEND_OPTIMIZER_PASS_1
#define ZEND_DUMP_AFTER_PASS_1
#define ZEND_DUMP_AFTER_PASS_11
#define ZEND_OPTIMIZER_PASS_11
#define ZEND_DUMP_BEFORE_OPTIMIZER
#define ZEND_OPTIMIZER_PASS_3
#define ZEND_DUMP_AFTER_PASS_13
#define ZEND_OPTIMIZER_PASS_5
#define ZEND_DUMP_AFTER_OPTIMIZER
#define ZEND_OPTIMIZER_PASS_13
#define ZEND_OPTIMIZER_PASS_6
#define ZEND_DUMP_AFTER_PASS_3
#define ZEND_DUMP_AFTER_PASS_10
#define ZEND_DUMP_AFTER_PASS_5
#define ZEND_DUMP_AFTER_PASS_6
#define ZEND_OPTIMIZER_PASS_12
#define ZEND_OPTIMIZER_PASS_4
#define ZEND_OPTIMIZER_PASS_7
#define ZEND_DUMP_AFTER_PASS_7
#define ZEND_DUMP_AFTER_PASS_9
#define ZEND_OPTIMIZER_PASS_10
#define ZEND_OP1_JMP_ADDR(opline)
#define ZEND_OP1_LITERAL(opline)
#define ZEND_OP2_LITERAL(opline)
#define ZEND_OP2_JMP_ADDR(opline)
struct _zend_optimizer_ctx zend_optimizer_ctx
void(* zend_op_array_func_t)(zend_op_array *, void *context)
#define XtOffsetOf(s_type, field)
struct _zend_class_entry zend_class_entry
struct _zend_ssa zend_ssa
struct _zend_ssa_op zend_ssa_op
#define zend_string_equals_literal(str, literal)
#define zend_string_equals_ci(s1, s2)
#define MAY_BE_ARRAY_OF_ANY
#define MAY_BE_ARRAY_KEY_ANY
#define Z_TRY_ADDREF_P(pz)
#define Z_STRVAL_P(zval_p)
#define ZVAL_STR_COPY(z, s)
struct _zend_array HashTable
#define Z_STRLEN_P(zval_p)
#define ZVAL_DOUBLE(z, d)
ZEND_RESULT_CODE zend_result
#define ZEND_TYPE_CONTAINS_CODE(t, code)
#define ZVAL_COPY_VALUE(z, v)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
#define IS_ABSOLUTE_PATH(path, len)
ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op *opcode, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)
#define ZEND_VM_SET_OPCODE_HANDLER(opline)
zend_property_info * prop_info
#define ZEND_FETCH_STATIC_PROP_IS
#define ZEND_IS_IDENTICAL
#define ZEND_ASSIGN_DIM_OP
#define ZEND_ASSIGN_STATIC_PROP_REF
#define ZEND_UNSET_STATIC_PROP
#define ZEND_ISSET_ISEMPTY_CV
#define ZEND_VERIFY_RETURN_TYPE
#define ZEND_FETCH_LIST_R
#define ZEND_FETCH_LIST_W
#define ZEND_ASSERT_CHECK
#define ZEND_RETURN_BY_REF
#define ZEND_SWITCH_STRING
#define ZEND_FETCH_OBJ_FUNC_ARG
#define ZEND_FETCH_STATIC_PROP_R
#define ZEND_PRE_DEC_STATIC_PROP
#define ZEND_ASSIGN_STATIC_PROP_OP
#define ZEND_FETCH_DIM_FUNC_ARG
#define ZEND_POST_INC_STATIC_PROP
#define ZEND_IS_NOT_EQUAL
#define ZEND_FETCH_STATIC_PROP_UNSET
#define ZEND_IS_NOT_IDENTICAL
#define ZEND_FETCH_OBJ_IS
#define ZEND_FETCH_OBJ_UNSET
#define ZEND_POST_DEC_OBJ
#define ZEND_ISSET_ISEMPTY_PROP_OBJ
#define ZEND_FETCH_STATIC_PROP_FUNC_ARG
#define ZEND_INIT_NS_FCALL_BY_NAME
#define ZEND_ADD_ARRAY_ELEMENT
#define ZEND_ISSET_ISEMPTY_STATIC_PROP
#define ZEND_ASSIGN_STATIC_PROP
#define ZEND_IS_SMALLER_OR_EQUAL
#define ZEND_POST_DEC_STATIC_PROP
#define ZEND_INIT_FCALL_BY_NAME
#define ZEND_PRE_INC_STATIC_PROP
#define ZEND_SEND_VAR_NO_REF_EX
#define ZEND_SEND_FUNC_ARG
#define ZEND_ISSET_ISEMPTY_DIM_OBJ
#define ZEND_ISSET_ISEMPTY_VAR
#define ZEND_BIND_INIT_STATIC_OR_JMP
#define ZEND_ARRAY_KEY_EXISTS
#define ZEND_JMP_FRAMELESS
#define ZEND_INIT_DYNAMIC_CALL
#define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
#define ZEND_FETCH_STATIC_PROP_W
#define ZEND_ASSIGN_OBJ_OP
#define ZEND_ASSIGN_OBJ_REF
#define ZEND_FETCH_STATIC_PROP_RW
#define ZEND_FETCH_CLASS_CONSTANT
#define ZEND_FETCH_DIM_IS
#define ZEND_FETCH_OBJ_RW
#define ZEND_FETCH_DIM_UNSET
#define ZEND_SEND_VAR_NO_REF
#define ZEND_POST_INC_OBJ
#define ZEND_INIT_METHOD_CALL
#define ZEND_INIT_STATIC_METHOD_CALL
#define ZEND_FETCH_FUNC_ARG
#define ZEND_FETCH_CLASS_NAME
#define ZEND_FETCH_DIM_RW