Merge branch 'PHP-5.5'

* PHP-5.5:
  Replce ZEND_FETCH_* instructions with IS_CV if possible

Conflicts:
	ext/opcache/Optimizer/zend_optimizer.c
This commit is contained in:
Dmitry Stogov 2013-08-09 17:52:22 +04:00
commit 2bc886abed
2 changed files with 81 additions and 0 deletions

View file

@ -438,6 +438,58 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
#endif #endif
collect_constants = 0; collect_constants = 0;
break; break;
#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
case ZEND_FETCH_R:
case ZEND_FETCH_W:
case ZEND_FETCH_RW:
case ZEND_FETCH_FUNC_ARG:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
if (opline != op_array->opcodes &&
(opline-1)->opcode == ZEND_BEGIN_SILENCE &&
(opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL &&
opline->op1_type == IS_CONST &&
opline->op2_type == IS_UNUSED &&
Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING &&
(Z_STRLEN(ZEND_OP1_LITERAL(opline)) != sizeof("this")-1 ||
memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this")) != 0)) {
int var = opline->result.var;
int level = 0;
zend_op *op = opline + 1;
while (op < end) {
if (op->opcode == ZEND_BEGIN_SILENCE) {
level++;
} else if (op->opcode == ZEND_END_SILENCE) {
if (level == 0) {
break;
} else {
level--;
}
}
if (op->op1_type == IS_VAR && op->op1.var == var) {
op->op1_type = IS_CV;
op->op1.var = zend_optimizer_lookup_cv(op_array,
Z_STRVAL(ZEND_OP1_LITERAL(opline)),
Z_STRLEN(ZEND_OP1_LITERAL(opline)));
MAKE_NOP(opline);
break;
} else if (op->op2_type == IS_VAR && op->op2.var == var) {
op->op2_type = IS_CV;
op->op2.var = zend_optimizer_lookup_cv(op_array,
Z_STRVAL(ZEND_OP1_LITERAL(opline)),
Z_STRLEN(ZEND_OP1_LITERAL(opline)));
MAKE_NOP(opline);
break;
}
op++;
}
}
break;
#endif
} }
opline++; opline++;
i++; i++;

View file

@ -59,6 +59,35 @@ static int zend_optimizer_get_collected_constant(HashTable *constants, zval *nam
return 0; return 0;
} }
#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len)
{
int i = 0;
ulong hash_value = zend_inline_hash_func(name, name_len+1);
while (i < op_array->last_var) {
if (op_array->vars[i].name == name ||
(op_array->vars[i].hash_value == hash_value &&
op_array->vars[i].name_len == name_len &&
memcmp(op_array->vars[i].name, name, name_len) == 0)) {
return i;
}
i++;
}
i = op_array->last_var;
op_array->last_var++;
op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable));
if (IS_INTERNED(name)) {
op_array->vars[i].name = name;
} else {
op_array->vars[i].name = estrndup(name, name_len);
}
op_array->vars[i].name_len = name_len;
op_array->vars[i].hash_value = hash_value;
return i;
}
#endif
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC)
{ {