]> granicus.if.org Git - php/commitdiff
Introduced BIND_STATIC opcode instead of FETCH_R/FETCH_W(static)+ASSIGN/ASSIGN_REF...
authorDmitry Stogov <dmitry@zend.com>
Tue, 12 Jan 2016 09:20:35 +0000 (12:20 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 12 Jan 2016 09:20:35 +0000 (12:20 +0300)
In the future we may refer to static variable by index instead of name, to eliminate hash lookup.

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h
ext/opcache/Optimizer/zend_dfg.c
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c

index e9cc4bf84c3d9e7d1a5cc14b8bfabfdc09c7eafe..2cc1a640aaba26569c226e963e86f89056f03076 100644 (file)
@@ -3746,16 +3746,10 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_
        }
        zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value);
 
-       opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL);
-       opline->extended_value = ZEND_FETCH_STATIC;
-
-       if (by_ref) {
-               zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
-               zend_emit_assign_ref_znode(fetch_ast, &result);
-       } else {
-               zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
-               zend_emit_assign_znode(fetch_ast, &result);
-       }
+       opline = zend_emit_op(NULL, ZEND_BIND_STATIC, NULL, &var_node);
+       opline->op1_type = IS_CV;
+       opline->op1.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR(var_node.u.constant)));
+       opline->extended_value = by_ref;
 }
 /* }}} */
 
index 2984f75b64a85e9bdd2cf43637bec2bb5d864fe7..5b5f19995a10cd6ba3b73f10698e070a01a02e02 100644 (file)
@@ -890,7 +890,6 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name);
 /* global/local fetches */
 #define ZEND_FETCH_GLOBAL                      0x00000000
 #define ZEND_FETCH_LOCAL                       0x10000000
-#define ZEND_FETCH_STATIC                      0x20000000
 #define ZEND_FETCH_GLOBAL_LOCK         0x40000000
 
 #define ZEND_FETCH_TYPE_MASK           0x70000000
index 8f30373e8747674d174a382f9c77c4985dbeb4bd..fffcb9cbb7b3c5e3c020cd5ce9a0b7381cd208a4 100644 (file)
@@ -1537,15 +1537,6 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
        if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
            EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
                ht = &EG(symbol_table);
-       } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
-               ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
-               ht = EX(func)->op_array.static_variables;
-               if (GC_REFCOUNT(ht) > 1) {
-                       if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
-                               GC_REFCOUNT(ht)--;
-                       }
-                       EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
-               }
        } else {
                ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
                if (!EX(symbol_table)) {
index b0637fcc55a27086edc8cab45b146c39fa80a7b2..47acc71e8f253e95c54d57c0e06592c87a40339b 100644 (file)
@@ -1474,14 +1474,7 @@ ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
                }
        }
 
-       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
-               if (Z_CONSTANT_P(retval)) {
-                       if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
-                               FREE_OP1();
-                               HANDLE_EXCEPTION();
-                       }
-               }
-       } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
+       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
                FREE_OP1();
        }
 
@@ -8028,4 +8021,55 @@ ZEND_VM_HANDLER(182, ZEND_BIND_LEXICAL, TMP, CV, REF)
        ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       HashTable *ht;
+       zval *varname;
+       zval *value;
+       zval *variable_ptr;
+
+       SAVE_OPLINE();
+       variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
+       zval_ptr_dtor(variable_ptr);
+
+       ht = EX(func)->op_array.static_variables;
+       ZEND_ASSERT(ht != NULL);
+       if (GC_REFCOUNT(ht) > 1) {
+               if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+                       GC_REFCOUNT(ht)--;
+               }
+               EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
+       }
+
+       varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
+       value = zend_hash_find(ht, Z_STR_P(varname));
+
+       if (opline->extended_value) {
+               if (Z_CONSTANT_P(value)) {
+                       if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
+                               ZVAL_NULL(variable_ptr);
+                               HANDLE_EXCEPTION();
+                       }
+               }
+               if (UNEXPECTED(!Z_ISREF_P(value))) {
+                       zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
+                       GC_REFCOUNT(ref) = 2;
+                       GC_TYPE_INFO(ref) = IS_REFERENCE;
+                       ZVAL_COPY_VALUE(&ref->val, value);
+                       Z_REF_P(value) = ref;
+                       Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
+                       ZVAL_REF(variable_ptr, ref);
+               } else {
+                       Z_ADDREF_P(value);
+                       ZVAL_REF(variable_ptr, Z_REF_P(value));
+               }
+       } else {
+               ZVAL_COPY(variable_ptr, value);
+       }
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
index 4de081d4760e9701bea0c7903111c82e08f56b0d..080c799f7a8c6e346346acf0012101e3bb00cfb2 100644 (file)
@@ -7199,14 +7199,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                }
        }
 
-       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
-               if (Z_CONSTANT_P(retval)) {
-                       if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
-
-                               HANDLE_EXCEPTION();
-                       }
-               }
-       } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
+       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
 
        }
 
@@ -32486,6 +32479,57 @@ check_indirect:
        ZEND_VM_NEXT_OPCODE();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       HashTable *ht;
+       zval *varname;
+       zval *value;
+       zval *variable_ptr;
+
+       SAVE_OPLINE();
+       variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var);
+       zval_ptr_dtor(variable_ptr);
+
+       ht = EX(func)->op_array.static_variables;
+       ZEND_ASSERT(ht != NULL);
+       if (GC_REFCOUNT(ht) > 1) {
+               if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
+                       GC_REFCOUNT(ht)--;
+               }
+               EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
+       }
+
+       varname = EX_CONSTANT(opline->op2);
+       value = zend_hash_find(ht, Z_STR_P(varname));
+
+       if (opline->extended_value) {
+               if (Z_CONSTANT_P(value)) {
+                       if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
+                               ZVAL_NULL(variable_ptr);
+                               HANDLE_EXCEPTION();
+                       }
+               }
+               if (UNEXPECTED(!Z_ISREF_P(value))) {
+                       zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference));
+                       GC_REFCOUNT(ref) = 2;
+                       GC_TYPE_INFO(ref) = IS_REFERENCE;
+                       ZVAL_COPY_VALUE(&ref->val, value);
+                       Z_REF_P(value) = ref;
+                       Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
+                       ZVAL_REF(variable_ptr, ref);
+               } else {
+                       Z_ADDREF_P(value);
+                       ZVAL_REF(variable_ptr, Z_REF_P(value));
+               }
+       } else {
+               ZVAL_COPY(variable_ptr, value);
+       }
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -33627,14 +33671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                }
        }
 
-       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
-               if (Z_CONSTANT_P(retval)) {
-                       if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
-
-                               HANDLE_EXCEPTION();
-                       }
-               }
-       } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
+       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
 
        }
 
@@ -42016,14 +42053,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_
                }
        }
 
-       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) {
-               if (Z_CONSTANT_P(retval)) {
-                       if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) {
-                               zval_ptr_dtor_nogc(free_op1);
-                               HANDLE_EXCEPTION();
-                       }
-               }
-       } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
+       if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) {
                zval_ptr_dtor_nogc(free_op1);
        }
 
@@ -49390,6 +49420,31 @@ void zend_init_opcodes_handlers(void)
        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_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = labels;
index a2ed83ee9e418d11cec1de8152ff7f868bbf782a..665efd65d1dba0876a6afbb6d7cceb479b902d3e 100644 (file)
@@ -21,7 +21,7 @@
 #include <stdio.h>
 #include <zend.h>
 
-static const char *zend_vm_opcodes_names[183] = {
+static const char *zend_vm_opcodes_names[184] = {
        "ZEND_NOP",
        "ZEND_ADD",
        "ZEND_SUB",
@@ -205,9 +205,10 @@ static const char *zend_vm_opcodes_names[183] = {
        "ZEND_ISSET_ISEMPTY_STATIC_PROP",
        "ZEND_FETCH_CLASS_CONSTANT",
        "ZEND_BIND_LEXICAL",
+       "ZEND_BIND_STATIC",
 };
 
-static uint32_t zend_vm_opcodes_flags[183] = {
+static uint32_t zend_vm_opcodes_flags[184] = {
        0x00000000,
        0x00000707,
        0x00000707,
@@ -391,6 +392,7 @@ static uint32_t zend_vm_opcodes_flags[183] = {
        0x00027307,
        0x00000373,
        0x00100101,
+       0x00100301,
 };
 
 ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
index bb677134c668d97fbafb2bb95947eaf15bb3f517..1b23b765161920ea05c96c5f558c1c52d948c355 100644 (file)
@@ -255,7 +255,8 @@ END_EXTERN_C()
 #define ZEND_ISSET_ISEMPTY_STATIC_PROP       180
 #define ZEND_FETCH_CLASS_CONSTANT            181
 #define ZEND_BIND_LEXICAL                    182
+#define ZEND_BIND_STATIC                     183
 
-#define ZEND_VM_LAST_OPCODE                  182
+#define ZEND_VM_LAST_OPCODE                  183
 
 #endif
index 65c19b21d99cbd6fc5b9f020f10c213a3cc4e710..9e71e00b65acc29a33cb3c6a6354d35afa45e194 100644 (file)
@@ -92,6 +92,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
                                        case ZEND_ASSIGN:
                                        case ZEND_ASSIGN_REF:
                                        case ZEND_BIND_GLOBAL:
+                                       case ZEND_BIND_STATIC:
                                        case ZEND_SEND_VAR_EX:
                                        case ZEND_SEND_REF:
                                        case ZEND_SEND_VAR_NO_REF:
index 1eacd401b165d23a633ee6ec095195a76f18a0a7..53458644fc70d94d2c5d4719ccd1e95460871171 100644 (file)
@@ -510,9 +510,6 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
                                case ZEND_FETCH_LOCAL:
                                        fprintf(stderr, " (local)");
                                        break;
-                               case ZEND_FETCH_STATIC:
-                                       fprintf(stderr, " (static)");
-                                       break;
                                case ZEND_FETCH_GLOBAL_LOCK:
                                        fprintf(stderr, " (global+lock)");
                                        break;
index 6bc7fb7a5364c98200070e945c5be2e6fdfd6cec..41bd4eebb052097db245194ec8bdee245b7453b8 100644 (file)
@@ -3067,6 +3067,7 @@ static void zend_update_type_info(const zend_op_array *op_array,
                        }
                        break;
                case ZEND_BIND_GLOBAL:
+               case ZEND_BIND_STATIC:
                        tmp = (MAY_BE_REF | MAY_BE_ANY );
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
                        break;
index b942391850076001370b8d15fb3eb697ef07323d..059550b63d8b0c9f4b849fa1b283debeb4e83944 100644 (file)
@@ -275,6 +275,7 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
                                        }
                                        break;
                                case ZEND_BIND_GLOBAL:
+                               case ZEND_BIND_STATIC:
                                        if (opline->op1_type == IS_CV) {
                                                ssa_ops[k].op1_def = ssa_vars_count;
                                                var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;