Skip to content

Commit

Permalink
Extract helper for fetching class entry in optimizer
Browse files Browse the repository at this point in the history
This code is repeated a few time. Two occurrences additionally
contained checks for user classes in CG(class_table) with the
same file name, but as far as I know these should always be in
the script class_table, so I'm omitting the check here.
  • Loading branch information
nikic committed Jun 18, 2021
1 parent d4ead60 commit 0d9269d
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 61 deletions.
22 changes: 4 additions & 18 deletions Zend/Optimizer/escape_analysis.c
Expand Up @@ -147,22 +147,6 @@ static int zend_build_equi_escape_sets(int *parent, zend_op_array *op_array, zen
}
/* }}} */

static inline zend_class_entry *get_class_entry(const zend_script *script, zend_string *lcname) /* {{{ */
{
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
if (ce) {
return ce;
}

ce = zend_hash_find_ptr(CG(class_table), lcname);
if (ce && ce->type == ZEND_INTERNAL_CLASS) {
return ce;
}

return NULL;
}
/* }}} */

static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var, const zend_script *script) /* {{{ */
{
zend_ssa_op *ssa_op = ssa->ops + def;
Expand All @@ -175,7 +159,8 @@ static int is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, in
case ZEND_NEW:
/* objects with destructors should escape */
if (opline->op1_type == IS_CONST) {
zend_class_entry *ce = get_class_entry(script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
zend_class_entry *ce = zend_optimizer_get_class_entry(
script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
uint32_t forbidden_flags =
/* These flags will always cause an exception */
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
Expand Down Expand Up @@ -242,7 +227,8 @@ static int is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var
case ZEND_NEW:
/* objects with destructors should escape */
if (opline->op1_type == IS_CONST) {
zend_class_entry *ce = get_class_entry(script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
zend_class_entry *ce = zend_optimizer_get_class_entry(
script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
if (ce && !ce->create_object && !ce->constructor &&
!ce->destructor && !ce->__get && !ce->__set && !ce->parent) {
return 1;
Expand Down
9 changes: 3 additions & 6 deletions Zend/Optimizer/pass1.c
Expand Up @@ -238,12 +238,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
zend_string_equals_ci(Z_STR(ZEND_OP1_LITERAL(opline)), op_array->scope->name)) {
ce = op_array->scope;
} else {
if ((ce = zend_hash_find_ptr(EG(class_table),
Z_STR(op_array->literals[opline->op1.constant + 1]))) == NULL ||
(ce->type == ZEND_INTERNAL_CLASS &&
ce->info.internal.module->type != MODULE_PERSISTENT) ||
(ce->type == ZEND_USER_CLASS &&
ce->info.user.filename != op_array->filename)) {
ce = zend_optimizer_get_class_entry(
ctx->script, Z_STR(op_array->literals[opline->op1.constant + 1]));
if (!ce) {
break;
}
}
Expand Down
25 changes: 6 additions & 19 deletions Zend/Optimizer/zend_inference.c
Expand Up @@ -22,6 +22,7 @@
#include "zend_func_info.h"
#include "zend_call_graph.h"
#include "zend_worklist.h"
#include "zend_optimizer_internal.h"

/* The used range inference algorithm is described in:
* V. Campos, R. Rodrigues, I. de Assis Costa and F. Pereira.
Expand Down Expand Up @@ -2189,20 +2190,6 @@ static uint32_t binary_op_result_type(
return tmp;
}

static inline zend_class_entry *get_class_entry(const zend_script *script, zend_string *lcname) {
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
if (ce) {
return ce;
}

ce = zend_hash_find_ptr(CG(class_table), lcname);
if (ce && ce->type == ZEND_INTERNAL_CLASS) {
return ce;
}

return NULL;
}

static uint32_t zend_convert_type_declaration_mask(uint32_t type_mask) {
uint32_t result_mask = type_mask & MAY_BE_ANY;
if (type_mask & MAY_BE_VOID) {
Expand Down Expand Up @@ -2238,7 +2225,7 @@ ZEND_API uint32_t zend_fetch_arg_info_type(const zend_script *script, zend_arg_i
/* As we only have space to store one CE, we use a plain object type for class unions. */
if (ZEND_TYPE_HAS_NAME(arg_info->type)) {
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(arg_info->type));
*pce = get_class_entry(script, lcname);
*pce = zend_optimizer_get_class_entry(script, lcname);
zend_string_release_ex(lcname, 0);
}
}
Expand Down Expand Up @@ -2320,7 +2307,7 @@ static zend_property_info *zend_fetch_static_prop_info(const zend_script *script
}
} else if (opline->op2_type == IS_CONST) {
zval *zv = CRT_CONSTANT(opline->op2);
ce = get_class_entry(script, Z_STR_P(zv + 1));
ce = zend_optimizer_get_class_entry(script, Z_STR_P(zv + 1));
}

if (ce) {
Expand Down Expand Up @@ -2348,7 +2335,7 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in
*pce = ZEND_TYPE_CE(prop_info->type);
} else if (ZEND_TYPE_HAS_NAME(prop_info->type)) {
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(prop_info->type));
*pce = get_class_entry(script, lcname);
*pce = zend_optimizer_get_class_entry(script, lcname);
zend_string_release(lcname);
}
}
Expand Down Expand Up @@ -3106,7 +3093,7 @@ static zend_always_inline int _zend_update_type_info(
} else if (opline->op2_type == IS_CONST) {
zval *zv = CRT_CONSTANT(opline->op2);
if (Z_TYPE_P(zv) == IS_STRING) {
ce = get_class_entry(script, Z_STR_P(zv+1));
ce = zend_optimizer_get_class_entry(script, Z_STR_P(zv+1));
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
} else {
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
Expand All @@ -3118,7 +3105,7 @@ static zend_always_inline int _zend_update_type_info(
case ZEND_NEW:
tmp = MAY_BE_RC1|MAY_BE_RCN|MAY_BE_OBJECT;
if (opline->op1_type == IS_CONST &&
(ce = get_class_entry(script, Z_STR_P(CRT_CONSTANT(opline->op1)+1))) != NULL) {
(ce = zend_optimizer_get_class_entry(script, Z_STR_P(CRT_CONSTANT(opline->op1)+1))) != NULL) {
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
} else if ((t1 & MAY_BE_CLASS) && ssa_op->op1_use >= 0 && ssa_var_info[ssa_op->op1_use].ce) {
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_op->op1_use].ce, ssa_var_info[ssa_op->op1_use].is_instanceof, ssa_op->result_def);
Expand Down
28 changes: 15 additions & 13 deletions Zend/Optimizer/zend_optimizer.c
Expand Up @@ -754,24 +754,26 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
}
}

zend_class_entry *zend_optimizer_get_class_entry(const zend_script *script, zend_string *lcname) {
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
if (ce) {
return ce;
}

ce = zend_hash_find_ptr(CG(class_table), lcname);
if (ce && ce->type == ZEND_INTERNAL_CLASS) {
return ce;
}

return NULL;
}

static zend_class_entry *get_class_entry_from_op1(
zend_script *script, zend_op_array *op_array, zend_op *opline) {
if (opline->op1_type == IS_CONST) {
zval *op1 = CRT_CONSTANT(opline->op1);
if (Z_TYPE_P(op1) == IS_STRING) {
zend_string *class_name = Z_STR_P(op1 + 1);
zend_class_entry *ce;
if (script && (ce = zend_hash_find_ptr(&script->class_table, class_name))) {
return ce;
} else if ((ce = zend_hash_find_ptr(EG(class_table), class_name))) {
if (ce->type == ZEND_INTERNAL_CLASS) {
return ce;
} else if (ce->type == ZEND_USER_CLASS &&
ce->info.user.filename &&
ce->info.user.filename == op_array->filename) {
return ce;
}
}
return zend_optimizer_get_class_entry(script, Z_STR_P(op1 + 1));
}
} else if (opline->op1_type == IS_UNUSED && op_array->scope
&& !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
Expand Down
1 change: 1 addition & 0 deletions Zend/Optimizer/zend_optimizer_internal.h
Expand Up @@ -96,6 +96,7 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
uint32_t var,
zval *val);
zend_op *zend_optimizer_get_loop_var_def(const zend_op_array *op_array, zend_op *free_opline);
zend_class_entry *zend_optimizer_get_class_entry(const zend_script *script, zend_string *lcname);

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);
Expand Down
7 changes: 2 additions & 5 deletions Zend/Optimizer/zend_ssa.c
Expand Up @@ -535,12 +535,9 @@ static void place_essa_pis(
(opline-1)->op2_type == IS_CONST) {
int var = EX_VAR_TO_NUM((opline-1)->op1.var);
zend_string *lcname = Z_STR_P(CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op2) + 1);
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
zend_class_entry *ce = zend_optimizer_get_class_entry(script, lcname);
if (!ce) {
ce = zend_hash_find_ptr(CG(class_table), lcname);
if (!ce || ce->type != ZEND_INTERNAL_CLASS) {
continue;
}
continue;
}

if ((pi = add_pi(arena, op_array, dfg, ssa, j, bt, var))) {
Expand Down

0 comments on commit 0d9269d

Please sign in to comment.