diff options
author | Dmitry Stogov <dmitry@zend.com> | 2013-08-09 17:47:47 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2013-08-09 17:47:47 +0400 |
commit | b27f6826d4d35caaf5b08e87297d13838930df94 (patch) | |
tree | d15ea89ff39a86d746cd0f5e3af093ea54bf9f18 | |
parent | b33824bfeaca68a6fec7b9066945fe171174c42c (diff) | |
download | php-git-b27f6826d4d35caaf5b08e87297d13838930df94.tar.gz |
Replce ZEND_FETCH_* instructions with IS_CV if possible
-rw-r--r-- | ext/opcache/Optimizer/pass1_5.c | 52 | ||||
-rw-r--r-- | ext/opcache/Optimizer/zend_optimizer.c | 29 |
2 files changed, 81 insertions, 0 deletions
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index dc9e7319a9..46406c383e 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -388,6 +388,58 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) { } } 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++; i++; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index a6450ab5c4..1f411d5da8 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -28,6 +28,35 @@ #define OPTIMIZATION_LEVEL \
ZCG(accel_directives).optimization_level
+#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
int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC)
{
|