diff options
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
| -rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 117 |
1 files changed, 93 insertions, 24 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index f9b21ff19e..07860f3998 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -206,7 +206,6 @@ int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv) op_array->last_literal++; op_array->literals = (zval*)erealloc(op_array->literals, op_array->last_literal * sizeof(zval)); ZVAL_COPY_VALUE(&op_array->literals[i], zv); - Z_CACHE_SLOT(op_array->literals[i]) = -1; return i; } @@ -232,13 +231,10 @@ static inline void drop_leading_backslash(zval *val) { } } -static inline void alloc_cache_slots_op1(zend_op_array *op_array, zend_op *opline, uint32_t num) { - Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size; - op_array->cache_size += num * sizeof(void *); -} -static inline void alloc_cache_slots_op2(zend_op_array *op_array, zend_op *opline, uint32_t num) { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; +static inline uint32_t alloc_cache_slots(zend_op_array *op_array, uint32_t num) { + uint32_t ret = op_array->cache_size; op_array->cache_size += num * sizeof(void *); + return ret; } #define REQUIRES_STRING(val) do { \ @@ -275,15 +271,43 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_RETURN_BY_REF: case ZEND_INSTANCEOF: return 0; - case ZEND_INIT_STATIC_METHOD_CALL: case ZEND_CATCH: - case ZEND_FETCH_CLASS_CONSTANT: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 1) | (opline->extended_value & ZEND_LAST_CATCH); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; case ZEND_DEFINED: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 1); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; case ZEND_NEW: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op1.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op1(op_array, opline, 1); + opline->op2.num = alloc_cache_slots(op_array, 1); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; + case ZEND_INIT_STATIC_METHOD_CALL: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type != IS_CONST) { + opline->result.num = alloc_cache_slots(op_array, 1); + } + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + break; + case ZEND_FETCH_CLASS_CONSTANT: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1); + } zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); break; case ZEND_FETCH_STATIC_PROP_R: @@ -292,9 +316,23 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_FETCH_STATIC_PROP_IS: case ZEND_FETCH_STATIC_PROP_UNSET: case ZEND_FETCH_STATIC_PROP_FUNC_ARG: + case ZEND_UNSET_STATIC_PROP: TO_STRING_NOWARN(val); opline->op1.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op1(op_array, opline, 2); + if (opline->op2_type == IS_CONST && opline->extended_value + sizeof(void*) == op_array->cache_size) { + op_array->cache_size += sizeof(void *); + } else { + opline->extended_value = alloc_cache_slots(op_array, 2); + } + break; + case ZEND_ISSET_ISEMPTY_STATIC_PROP: + TO_STRING_NOWARN(val); + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (opline->op2_type == IS_CONST && (opline->extended_value & ~ZEND_ISSET) + sizeof(void*) == op_array->cache_size) { + op_array->cache_size += sizeof(void *); + } else { + opline->extended_value = alloc_cache_slots(op_array, 2) | (opline->extended_value & ZEND_ISSET); + } break; case ZEND_SEND_VAR: opline->opcode = ZEND_SEND_VAL; @@ -351,11 +389,22 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, (opline + 1)->op2.var == opline->result.var) { return 0; } - case ZEND_INIT_FCALL_BY_NAME: - /*case ZEND_INIT_NS_FCALL_BY_NAME:*/ case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->extended_value = alloc_cache_slots(op_array, 1); + break; + case ZEND_INIT_FCALL_BY_NAME: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->result.num = alloc_cache_slots(op_array, 1); + break; case ZEND_FETCH_STATIC_PROP_R: case ZEND_FETCH_STATIC_PROP_W: case ZEND_FETCH_STATIC_PROP_RW: @@ -363,12 +412,22 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_FETCH_STATIC_PROP_UNSET: case ZEND_FETCH_STATIC_PROP_FUNC_ARG: case ZEND_UNSET_STATIC_PROP: + REQUIRES_STRING(val); + drop_leading_backslash(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + if (opline->op1_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1); + } + break; case ZEND_ISSET_ISEMPTY_STATIC_PROP: REQUIRES_STRING(val); drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 1); + if (opline->op1_type != IS_CONST) { + opline->extended_value = alloc_cache_slots(op_array, 1) | (opline->extended_value & ZEND_ISSET); + } break; case ZEND_INIT_FCALL: REQUIRES_STRING(val); @@ -380,7 +439,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, val = &tmp; } opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 1); + opline->result.num = alloc_cache_slots(op_array, 1); break; case ZEND_INIT_DYNAMIC_CALL: if (Z_TYPE_P(val) == IS_STRING) { @@ -398,19 +457,25 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, drop_leading_backslash(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 1); + opline->result.num = alloc_cache_slots(op_array, 1); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } break; case ZEND_INIT_METHOD_CALL: + REQUIRES_STRING(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); + opline->result.num = alloc_cache_slots(op_array, 2); + break; case ZEND_INIT_STATIC_METHOD_CALL: REQUIRES_STRING(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val))); - alloc_cache_slots_op2(op_array, opline, 2); + if (opline->op1_type != IS_CONST) { + opline->result.num = alloc_cache_slots(op_array, 2); + } break; - /*case ZEND_FETCH_CLASS_CONSTANT:*/ case ZEND_ASSIGN_OBJ: case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_W: @@ -423,10 +488,14 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_PRE_DEC_OBJ: case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: + TO_STRING_NOWARN(val); + opline->op2.constant = zend_optimizer_add_literal(op_array, val); + opline->extended_value = alloc_cache_slots(op_array, 2); + break; case ZEND_ISSET_ISEMPTY_PROP_OBJ: TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 2); + opline->extended_value = alloc_cache_slots(op_array, 2) | (opline->extended_value & ZEND_ISSET); break; case ZEND_ASSIGN_ADD: case ZEND_ASSIGN_SUB: @@ -443,7 +512,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, if (opline->extended_value == ZEND_ASSIGN_OBJ) { TO_STRING_NOWARN(val); opline->op2.constant = zend_optimizer_add_literal(op_array, val); - alloc_cache_slots_op2(op_array, opline, 2); + (opline+1)->extended_value = alloc_cache_slots(op_array, 2); } else { opline->op2.constant = zend_optimizer_add_literal(op_array, val); } @@ -766,7 +835,7 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline)); } break; @@ -806,7 +875,7 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_ ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]); break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]); } break; @@ -1174,7 +1243,7 @@ static void zend_redo_pass_two(zend_op_array *op_array) opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; } break; @@ -1260,7 +1329,7 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa) opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; break; case ZEND_CATCH: - if (opline->extended_value != ZEND_LAST_CATCH) { + if (!(opline->extended_value & ZEND_LAST_CATCH)) { opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; } break; |
