Skip to content

Commit b27f682

Browse files
committed
Replce ZEND_FETCH_* instructions with IS_CV if possible
1 parent b33824b commit b27f682

File tree

2 files changed

+81
-0
lines changed

2 files changed

+81
-0
lines changed

ext/opcache/Optimizer/pass1_5.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,58 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
388388
}
389389
}
390390
break;
391+
392+
#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
393+
case ZEND_FETCH_R:
394+
case ZEND_FETCH_W:
395+
case ZEND_FETCH_RW:
396+
case ZEND_FETCH_FUNC_ARG:
397+
case ZEND_FETCH_IS:
398+
case ZEND_FETCH_UNSET:
399+
if (opline != op_array->opcodes &&
400+
(opline-1)->opcode == ZEND_BEGIN_SILENCE &&
401+
(opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL &&
402+
opline->op1_type == IS_CONST &&
403+
opline->op2_type == IS_UNUSED &&
404+
Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING &&
405+
(Z_STRLEN(ZEND_OP1_LITERAL(opline)) != sizeof("this")-1 ||
406+
memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this")) != 0)) {
407+
408+
int var = opline->result.var;
409+
int level = 0;
410+
zend_op *op = opline + 1;
411+
412+
while (op < end) {
413+
if (op->opcode == ZEND_BEGIN_SILENCE) {
414+
level++;
415+
} else if (op->opcode == ZEND_END_SILENCE) {
416+
if (level == 0) {
417+
break;
418+
} else {
419+
level--;
420+
}
421+
}
422+
if (op->op1_type == IS_VAR && op->op1.var == var) {
423+
op->op1_type = IS_CV;
424+
op->op1.var = zend_optimizer_lookup_cv(op_array,
425+
Z_STRVAL(ZEND_OP1_LITERAL(opline)),
426+
Z_STRLEN(ZEND_OP1_LITERAL(opline)));
427+
MAKE_NOP(opline);
428+
break;
429+
} else if (op->op2_type == IS_VAR && op->op2.var == var) {
430+
op->op2_type = IS_CV;
431+
op->op2.var = zend_optimizer_lookup_cv(op_array,
432+
Z_STRVAL(ZEND_OP1_LITERAL(opline)),
433+
Z_STRLEN(ZEND_OP1_LITERAL(opline)));
434+
MAKE_NOP(opline);
435+
break;
436+
}
437+
op++;
438+
}
439+
}
440+
break;
441+
#endif
442+
391443
}
392444
opline++;
393445
i++;

ext/opcache/Optimizer/zend_optimizer.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,35 @@
2828
#define OPTIMIZATION_LEVEL \
2929
ZCG(accel_directives).optimization_level
3030

31+
#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
32+
static int zend_optimizer_lookup_cv(zend_op_array *op_array, char* name, int name_len)
33+
{
34+
int i = 0;
35+
ulong hash_value = zend_inline_hash_func(name, name_len+1);
36+
37+
while (i < op_array->last_var) {
38+
if (op_array->vars[i].name == name ||
39+
(op_array->vars[i].hash_value == hash_value &&
40+
op_array->vars[i].name_len == name_len &&
41+
memcmp(op_array->vars[i].name, name, name_len) == 0)) {
42+
return i;
43+
}
44+
i++;
45+
}
46+
i = op_array->last_var;
47+
op_array->last_var++;
48+
op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable));
49+
if (IS_INTERNED(name)) {
50+
op_array->vars[i].name = name;
51+
} else {
52+
op_array->vars[i].name = estrndup(name, name_len);
53+
}
54+
op_array->vars[i].name_len = name_len;
55+
op_array->vars[i].hash_value = hash_value;
56+
return i;
57+
}
58+
#endif
59+
3160
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
3261
int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC)
3362
{

0 commit comments

Comments
 (0)