com php-src: Replce ZEND_FETCH_* instructions with IS _CV if possible: ext/opcache/Optimizer/pass1_5 .c ext/opcache/Optimizer/zend_optimizer.c
| From: | Dmitry Stogov | Date: | Fri, 09 Aug 2013 13:47:47 +0000 |
| Subject: | com php-src: Replce ZEND_FETCH_* instructions with IS _CV if possible: ext/opcache/Optimizer/pass1_5 .c ext/opcache/Optimizer/zend_optimizer.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-72878@lists.php.net to get a copy of this message | ||
Commit: b27f6826d4d35caaf5b08e87297d13838930df94
Author: Dmitry Stogov <dmitry@zend.com> Fri, 9 Aug 2013 17:47:47 +0400
Parents: b33824bfeaca68a6fec7b9066945fe171174c42c
Branches: PHP-5.5
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=b27f6826d4d35caaf5b08e87297d13838930df94
Log:
Replce ZEND_FETCH_* instructions with IS_CV if possible
Changed paths:
M ext/opcache/Optimizer/pass1_5.c
M ext/opcache/Optimizer/zend_optimizer.c
Diff:
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index dc9e731..46406c3 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 a6450ab..1f411d5 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)
{