summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_optimizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c117
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;