]> granicus.if.org Git - php/commitdiff
Get rid of zend_op_array.early_binding
authorDmitry Stogov <dmitry@zend.com>
Thu, 11 Jan 2018 16:15:52 +0000 (19:15 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 11 Jan 2018 16:15:52 +0000 (19:15 +0300)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_opcode.c
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/Optimizer/nop_removal.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/Optimizer/zend_optimizer.h
ext/opcache/Optimizer/zend_optimizer_internal.h
ext/opcache/ZendAccelerator.c
ext/opcache/zend_accelerator_util_funcs.c

index 68cd87d40ba78aa397579e7c4f096bfc55d3d346..dbabfb36338bb4ada95bf60e4b990a2d996a5068 100644 (file)
@@ -1217,12 +1217,7 @@ void zend_do_early_binding(void) /* {{{ */
                                    ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
                                     (ce->type == ZEND_INTERNAL_CLASS))) {
                                        if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
-                                               uint32_t *opline_num = &CG(active_op_array)->early_binding;
-
-                                               while (*opline_num != (uint32_t)-1) {
-                                                       opline_num = &CG(active_op_array)->opcodes[*opline_num].result.opline_num;
-                                               }
-                                               *opline_num = opline - CG(active_op_array)->opcodes;
+                                               CG(active_op_array)->fn_flags |= ZEND_ACC_EARLY_BINDING;
                                                opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
                                                opline->result_type = IS_UNUSED;
                                                opline->result.opline_num = -1;
@@ -1287,11 +1282,33 @@ static void zend_mark_function_as_generator() /* {{{ */
 }
 /* }}} */
 
-ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array) /* {{{ */
+ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array) /* {{{ */
+{
+       if (op_array->fn_flags & ZEND_ACC_EARLY_BINDING) {
+               uint32_t  first_early_binding_opline = (uint32_t)-1;
+               uint32_t *prev_opline_num = &first_early_binding_opline;
+               zend_op  *opline = op_array->opcodes;
+               zend_op  *end = opline + op_array->last;
+
+               while (opline < end) {
+                       if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
+                               *prev_opline_num = opline - op_array->opcodes;
+                               prev_opline_num = &opline->result.opline_num;
+                       }
+                       ++opline;
+               }
+               *prev_opline_num = -1;
+               return first_early_binding_opline;
+       }
+       return (uint32_t)-1;
+}
+/* }}} */
+
+ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array, uint32_t first_early_binding_opline) /* {{{ */
 {
-       if (op_array->early_binding != (uint32_t)-1) {
+       if (first_early_binding_opline != (uint32_t)-1) {
                zend_bool orig_in_compilation = CG(in_compilation);
-               uint32_t opline_num = op_array->early_binding;
+               uint32_t opline_num = first_early_binding_opline;
                zend_class_entry *ce;
 
                CG(in_compilation) = 1;
index c9aa2261e58a5a607f96d5c055697eef841dbbbf..1b0d0d9d32b1256af0895f9e70fade47e1fb67be 100644 (file)
@@ -203,7 +203,6 @@ typedef struct _zend_oparray_context {
  * Free flags:
  * 0x10
  * 0x20
- * 0x8000
  * 0x2000000
  */
 
@@ -227,6 +226,9 @@ typedef struct _zend_oparray_context {
 #define ZEND_ACC_CTOR          0x2000
 #define ZEND_ACC_DTOR          0x4000
 
+/* "main" op_array with ZEND_DECLARE_INHERITED_CLASS_DELAYED opcodes */
+#define ZEND_ACC_EARLY_BINDING 0x8000
+
 /* method flag used by Closure::__invoke() */
 #define ZEND_ACC_USER_ARG_INFO 0x80
 
@@ -392,7 +394,6 @@ struct _zend_op_array {
        uint32_t line_start;
        uint32_t line_end;
        zend_string *doc_comment;
-       uint32_t early_binding; /* the linked list of delayed declarations */
 
        int last_literal;
        zval *literals;
@@ -723,7 +724,8 @@ void zend_do_free(znode *op1);
 ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opline, HashTable *function_table, zend_bool compile_time);
 ZEND_API zend_class_entry *do_bind_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time);
 ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time);
-ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array);
+ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array);
+ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array, uint32_t first_early_binding_opline);
 
 void zend_do_extended_info(void);
 void zend_do_extended_fcall_begin(void);
index 4cb423d216fc217fbcb70c5ac2d86eade2f3b43b..84470a59e4abd9c7a6886e2ffc769a2e60a1f085 100644 (file)
@@ -87,8 +87,6 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
 
        op_array->fn_flags = 0;
 
-       op_array->early_binding = -1;
-
        op_array->last_literal = 0;
        op_array->literals = NULL;
 
index 8207eafa813b19fcc90b36a692af08854bcb289f..da4f7e59028dbec34277d7224a932d114ec2df70 100644 (file)
@@ -876,7 +876,7 @@ optimize_const_unary_op:
 }
 
 /* Rebuild plain (optimized) op_array from CFG */
-static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
+static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_optimizer_ctx *ctx)
 {
        zend_basic_block *blocks = cfg->blocks;
        zend_basic_block *end = blocks + cfg->blocks_count;
@@ -1093,20 +1093,10 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
        }
 
        /* adjust early binding list */
-       if (op_array->early_binding != (uint32_t)-1) {
-               uint32_t *opline_num = &op_array->early_binding;
-               zend_op *end;
-
-               opline = op_array->opcodes;
-               end = opline + op_array->last;
-               while (opline < end) {
-                       if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
-                               *opline_num = opline - op_array->opcodes;
-                               opline_num = &opline->result.opline_num;
-                       }
-                       ++opline;
-               }
-               *opline_num = -1;
+       if (op_array->fn_flags & ZEND_ACC_EARLY_BINDING) {
+               ZEND_ASSERT(op_array == &ctx->script->main_op_array);
+               ctx->script->first_early_binding_opline =
+                       zend_build_delayed_early_binding_list(op_array);
        }
 
        /* rebuild map (just for printing) */
@@ -1953,7 +1943,7 @@ void zend_optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx)
 
        zend_bitset_clear(usage, bitset_len);
        zend_t_usage(&cfg, op_array, usage, ctx);
-       assemble_code_blocks(&cfg, op_array);
+       assemble_code_blocks(&cfg, op_array, ctx);
 
        if (ctx->debug_level & ZEND_DUMP_AFTER_BLOCK_PASS) {
                zend_dump_op_array(op_array, ZEND_DUMP_CFG | ZEND_DUMP_HIDE_UNREACHABLE, "after block pass", &cfg);
index 61047e8064cd94808ac74f2e3b406631adfa9d24..f24d407eeb0c348899828744d5d1a7c1ae97db1f 100644 (file)
@@ -125,7 +125,7 @@ int zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx,
        return SUCCESS;
 }
 
-static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
+static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_optimizer_ctx *ctx)
 {
        zend_basic_block *blocks = ssa->cfg.blocks;
        zend_basic_block *end = blocks + ssa->cfg.blocks_count;
@@ -263,9 +263,10 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
                }
 
                /* update early binding list */
-               if (op_array->early_binding != (uint32_t)-1) {
-                       uint32_t *opline_num = &op_array->early_binding;
+               if (op_array->fn_flags & ZEND_ACC_EARLY_BINDING) {
+                       uint32_t *opline_num = &ctx->script->first_early_binding_opline;
 
+                       ZEND_ASSERT(op_array == &ctx->script->main_op_array);
                        do {
                                *opline_num -= shiftlist[*opline_num];
                                opline_num = &op_array->opcodes[*opline_num].result.opline_num;
@@ -1177,7 +1178,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
 #endif
 
                if (remove_nops) {
-                       zend_ssa_remove_nops(op_array, ssa);
+                       zend_ssa_remove_nops(op_array, ssa, ctx);
 #if ZEND_DEBUG_DFA
                        ssa_verify_integrity(op_array, ssa, "after nop");
 #endif
index 9d8377cedc5b3da9739fae3a2216f7efbcccbc9d..c7ecad4d0e8010bbf1a468f24b79e2d8e284af43 100644 (file)
@@ -31,7 +31,7 @@
 #include "zend_execute.h"
 #include "zend_vm.h"
 
-void zend_optimizer_nop_removal(zend_op_array *op_array)
+void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx)
 {
        zend_op *end, *opline;
        uint32_t new_count, i, shift;
@@ -98,9 +98,10 @@ void zend_optimizer_nop_removal(zend_op_array *op_array)
                }
 
                /* update early binding list */
-               if (op_array->early_binding != (uint32_t)-1) {
-                       uint32_t *opline_num = &op_array->early_binding;
+               if (op_array->fn_flags & ZEND_ACC_EARLY_BINDING) {
+                       uint32_t *opline_num = &ctx->script->first_early_binding_opline;
 
+                       ZEND_ASSERT(op_array == &ctx->script->main_op_array);
                        do {
                                *opline_num -= shiftlist[*opline_num];
                                opline_num = &op_array->opcodes[*opline_num].result.opline_num;
index d5975f141418244e07becaba2a15fa3fa9ee6a12..a5ac88651c3f244f35926457042a3377cbaa4538 100644 (file)
@@ -1055,7 +1055,7 @@ static void zend_optimize(zend_op_array      *op_array,
         * - remove NOPs
         */
        if (((ZEND_OPTIMIZER_PASS_10|ZEND_OPTIMIZER_PASS_5) & ctx->optimization_level) == ZEND_OPTIMIZER_PASS_10) {
-               zend_optimizer_nop_removal(op_array);
+               zend_optimizer_nop_removal(op_array, ctx);
                if (ctx->debug_level & ZEND_DUMP_AFTER_PASS_10) {
                        zend_dump_op_array(op_array, 0, "after pass 10", NULL);
                }
index 27b7cedd38c244f851100d0c933f33b4a86e03f1..e1c96bec4591c4a5afc676dfc840146d155c3c15 100644 (file)
@@ -84,6 +84,7 @@ typedef struct _zend_script {
        zend_op_array  main_op_array;
        HashTable      function_table;
        HashTable      class_table;
+       uint32_t       first_early_binding_opline; /* the linked list of delayed declarations */
 } zend_script;
 
 int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level);
index 07decce3b4feb93559321f1e13b3de36ccfdf7f3..914e6e717a8fca6c27cd6ec66fcf831dccb4de2c 100644 (file)
@@ -102,7 +102,7 @@ void zend_optimize_dfa(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 int  zend_dfa_analyze_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa);
 void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx, zend_ssa *ssa, zend_call_info **call_map);
 void zend_optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx);
-void zend_optimizer_nop_removal(zend_op_array *op_array);
+void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx);
 void zend_optimizer_compact_vars(zend_op_array *op_array);
 int zend_optimizer_is_disabled_func(const char *name, size_t len);
index 347b5d6ed4ea06b3978c80716ab86716c6ffaa8a..aa84b318c3848a6d30318cec830c80d51a9d8679 100644 (file)
@@ -1723,6 +1723,10 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
           further anyway.
        */
        zend_accel_move_user_functions(&ZCG(function_table), &new_persistent_script->script.function_table);
+       new_persistent_script->script.first_early_binding_opline =
+               (op_array->fn_flags & ZEND_ACC_EARLY_BINDING) ?
+                       zend_build_delayed_early_binding_list(op_array) :
+                       (uint32_t)-1;
        new_persistent_script->script.main_op_array = *op_array;
 
        efree(op_array); /* we have valid persistent_script, so it's safe to free op_array */
index ce0c8f4adaea3465afeb6cc53777cdc707f36737..1e9b5e9868cd2abeb4e54f52116ebe706f173a49 100644 (file)
@@ -733,10 +733,10 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
                }
        }
 
-       if (op_array->early_binding != (uint32_t)-1) {
+       if (persistent_script->script.first_early_binding_opline != (uint32_t)-1) {
                zend_string *orig_compiled_filename = CG(compiled_filename);
                CG(compiled_filename) = persistent_script->script.filename;
-               zend_do_delayed_early_binding(op_array);
+               zend_do_delayed_early_binding(op_array, persistent_script->script.first_early_binding_opline);
                CG(compiled_filename) = orig_compiled_filename;
        }