com php-src: Introduced new BIND_GLOBAL instraction inste ad of FETCH_W+ASSIGN_REF pair that caused a l ot of useles checks: Zend/zend_compile.c
Zend/z end_vm_def.h Zend/zend_vm_execute.h Zend/zend _vm_opcodes.c Zend/zend_vm_opcodes.h
| From: | Dmitry Stogov | Date: | Fri, 06 Jun 2014 11:04:30 +0000 |
| Subject: | com php-src: Introduced new BIND_GLOBAL instraction inste ad of FETCH_W+ASSIGN_REF pair that caused a l ot of useles checks: Zend/zend_compile.c Zend/z end_vm_def.h Zend/zend_vm_execute.h Zend/zend _vm_opcodes.c Zend/zend_vm_opcodes.h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-78717@lists.php.net to get a copy of this message | ||
Commit: e499c3d25930ffc16d330b9b28ab2e70863dbce7
Author: Dmitry Stogov <dmitry@zend.com> Fri, 6 Jun 2014 15:04:30 +0400
Parents: e4581fd6b85cc4a2966d9df98ce0ce74405d58fc
Branches: phpng
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e499c3d25930ffc16d330b9b28ab2e70863dbce7
Log:
Introduced new BIND_GLOBAL instraction instead of FETCH_W+ASSIGN_REF pair that caused a lot of
useles checks
Changed paths:
M Zend/zend_compile.c
M Zend/zend_vm_def.h
M Zend/zend_vm_execute.h
M Zend/zend_vm_opcodes.c
M Zend/zend_vm_opcodes.h
Diff:
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index c84937b..de45b5a 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -6257,21 +6257,33 @@ void zend_do_fetch_global_variable(znode *varname, const znode
*static_assignmen
}
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = ZEND_FETCH_W; /* the default mode must be Write, since
fetch_simple_variable() is used to define function arguments */
- opline->result_type = IS_VAR;
- opline->result.var = get_temporary_variable(CG(active_op_array));
- SET_NODE(opline->op1, varname);
- SET_UNUSED(opline->op2);
- opline->extended_value = fetch_type;
- GET_NODE(&result, opline->result);
- if (varname->op_type == IS_CONST) {
+ if (varname->op_type == IS_CONST &&
+ !zend_is_auto_global(Z_STR(varname->u.constant) TSRMLS_CC) &&
+ !(Z_STRLEN(varname->u.constant) == (sizeof("this")-1) &&
+ !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1)))
{
+ opline->opcode = ZEND_BIND_GLOBAL;
+ SET_NODE(opline->op2, varname);
+ opline->op1_type = IS_CV;
zval_copy_ctor(&varname->u.constant);
- }
- fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default
fetch is BP_VAR_W */
+ opline->op1.var = lookup_cv(CG(active_op_array), Z_STR(varname->u.constant) TSRMLS_CC);
+ } else {
+ opline->opcode = ZEND_FETCH_W; /* the default mode must be Write, since
fetch_simple_variable() is used to define function arguments */
+ opline->result_type = IS_VAR;
+ opline->result.var = get_temporary_variable(CG(active_op_array));
+ SET_NODE(opline->op1, varname);
+ SET_UNUSED(opline->op2);
+ opline->extended_value = fetch_type;
+ GET_NODE(&result, opline->result);
- zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
- CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
+ if (varname->op_type == IS_CONST) {
+ zval_copy_ctor(&varname->u.constant);
+ }
+ fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default
fetch is BP_VAR_W */
+
+ zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
+ CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
+ }
}
/* }}} */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 8aa60ce..9542419 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5624,4 +5624,34 @@ ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op,pow_function);
}
+ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
+{
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *varname;
+ zval *value;
+ zval *variable_ptr;
+ zend_string *name;
+
+ SAVE_OPLINE();
+ varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
+ name = Z_STR_P(varname);
+ value = zend_hash_find(&EG(symbol_table).ht, name);
+ if (value == NULL) {
+ value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
+ /* GLOBAL variable may be an INDIRECT pointer to CV */
+ } else if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) == IS_UNDEF) {
+ ZVAL_NULL(value);
+ }
+ }
+
+ variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
+ zend_assign_to_variable_reference(variable_ptr, value TSRMLS_CC);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 1babe85...b1198b2 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute..h
@@ -33168,6 +33168,36 @@ static int ZEND_FASTCALL
ZEND_ASSIGN_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
return zend_binary_assign_op_helper_SPEC_CV_CONST(pow_function,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *varname;
+ zval *value;
+ zval *variable_ptr;
+ zend_string *name;
+
+ SAVE_OPLINE();
+ varname = opline->op2.zv;
+ name = Z_STR_P(varname);
+ value = zend_hash_find(&EG(symbol_table).ht, name);
+ if (value == NULL) {
+ value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
+ /* GLOBAL variable may be an INDIRECT pointer to CV */
+ } else if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) == IS_UNDEF) {
+ ZVAL_NULL(value);
+ }
+ }
+
+ variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ zend_assign_to_variable_reference(variable_ptr, value TSRMLS_CC);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -44468,6 +44498,31 @@ void zend_init_opcodes_handlers(void)
ZEND_ASSIGN_POW_SPEC_CV_VAR_HANDLER,
ZEND_ASSIGN_POW_SPEC_CV_UNUSED_HANDLER,
ZEND_ASSIGN_POW_SPEC_CV_CV_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 23edabc..df12703 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -21,7 +21,7 @@
#include <stdio.h>
#include <zend.h>
-const char *zend_vm_opcodes_map[168] = {
+const char *zend_vm_opcodes_map[169] = {
"ZEND_NOP",
"ZEND_ADD",
"ZEND_SUB",
@@ -190,6 +190,7 @@ const char *zend_vm_opcodes_map[168] = {
"ZEND_SEND_UNPACK",
"ZEND_POW",
"ZEND_ASSIGN_POW",
+ "ZEND_BIND_GLOBAL",
};
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index f9c30ca..df499f9 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -173,5 +173,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_SEND_UNPACK 165
#define ZEND_POW 166
#define ZEND_ASSIGN_POW 167
+#define ZEND_BIND_GLOBAL 168
#endif