]> granicus.if.org Git - php/commitdiff
Mark classes cached by opcache by ZEND_ACC_CACHED flag and prevent useless copying...
authorDmitry Stogov <dmitry@zend.com>
Tue, 19 Jan 2021 08:55:09 +0000 (11:55 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 19 Jan 2021 08:55:09 +0000 (11:55 +0300)
Zend/zend_compile.h
Zend/zend_inheritance.c
Zend/zend_opcode.c
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c

index 9f76c78f0d3be0ee293c850715c38e1a8fb2866d..b91e0038a40c1f8a04eca59fc00eb99468b73a9d 100644 (file)
@@ -238,7 +238,7 @@ typedef struct _zend_oparray_context {
 /* op_array or class is preloaded                         |     |     |     */
 #define ZEND_ACC_PRELOADED               (1 << 10) /*  X  |  X  |     |     */
 /*                                                        |     |     |     */
-/* Class Flags (unused: 22...)                            |     |     |     */
+/* Class Flags (unused: 23...)                            |     |     |     */
 /* ===========                                            |     |     |     */
 /*                                                        |     |     |     */
 /* Special class types                                    |     |     |     */
@@ -287,6 +287,9 @@ typedef struct _zend_oparray_context {
 /* Whether this class was used in its unlinked state.     |     |     |     */
 #define ZEND_ACC_HAS_UNLINKED_USES       (1 << 21) /*  X  |     |     |     */
 /*                                                        |     |     |     */
+/* stored in opcache (may be partially)                   |     |     |     */
+#define ZEND_ACC_CACHED                  (1 << 22) /*  X  |     |     |     */
+/*                                                        |     |     |     */
 /* Function Flags (unused: 27-30)                         |     |     |     */
 /* ==============                                         |     |     |     */
 /*                                                        |     |     |     */
index de7e70f1697659479a2008bf50edd517f5e47cda..16e31a10d8744160967cdffdea83774e7f31c444 100644 (file)
@@ -1549,11 +1549,13 @@ static void zend_do_implement_interfaces(zend_class_entry *ce, zend_class_entry
                }
        }
 
-       for (i = 0; i < ce->num_interfaces; i++) {
-               zend_string_release_ex(ce->interface_names[i].name, 0);
-               zend_string_release_ex(ce->interface_names[i].lc_name, 0);
+       if (!(ce->ce_flags & ZEND_ACC_CACHED)) {
+               for (i = 0; i < ce->num_interfaces; i++) {
+                       zend_string_release_ex(ce->interface_names[i].name, 0);
+                       zend_string_release_ex(ce->interface_names[i].lc_name, 0);
+               }
+               efree(ce->interface_names);
        }
-       efree(ce->interface_names);
 
        ce->num_interfaces = num_interfaces;
        ce->interfaces = interfaces;
index c9c65343f59aef7af00496c0da86d2fe6a89da8a..ae9bf2d74d4ed8785773318de310dc80e6aee6bf 100644 (file)
@@ -280,9 +280,37 @@ ZEND_API void destroy_zend_class(zval *zv)
        }
        switch (ce->type) {
                case ZEND_USER_CLASS:
-                       if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_RESOLVED_PARENT)) {
-                               zend_string_release_ex(ce->parent_name, 0);
+                       if (!(ce->ce_flags & ZEND_ACC_CACHED)) {
+                               if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_RESOLVED_PARENT)) {
+                                       zend_string_release_ex(ce->parent_name, 0);
+                               }
+
+                               zend_string_release_ex(ce->name, 0);
+                               zend_string_release_ex(ce->info.user.filename, 0);
+
+                               if (ce->info.user.doc_comment) {
+                                       zend_string_release_ex(ce->info.user.doc_comment, 0);
+                               }
+
+                               if (ce->attributes) {
+                                       zend_hash_release(ce->attributes);
+                               }
+
+                               if (ce->num_interfaces > 0 && !(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
+                                       uint32_t i;
+
+                                       for (i = 0; i < ce->num_interfaces; i++) {
+                                               zend_string_release_ex(ce->interface_names[i].name, 0);
+                                               zend_string_release_ex(ce->interface_names[i].lc_name, 0);
+                                       }
+                                       efree(ce->interface_names);
+                               }
+
+                               if (ce->num_traits > 0) {
+                                       _destroy_zend_class_traits_info(ce);
+                               }
                        }
+
                        if (ce->default_properties_table) {
                                zval *p = ce->default_properties_table;
                                zval *end = p + ce->default_properties_count;
@@ -325,7 +353,6 @@ ZEND_API void destroy_zend_class(zval *zv)
                                }
                        } ZEND_HASH_FOREACH_END();
                        zend_hash_destroy(&ce->properties_info);
-                       zend_string_release_ex(ce->name, 0);
                        zend_hash_destroy(&ce->function_table);
                        if (zend_hash_num_elements(&ce->constants_table)) {
                                zend_class_constant *c;
@@ -343,29 +370,9 @@ ZEND_API void destroy_zend_class(zval *zv)
                                } ZEND_HASH_FOREACH_END();
                        }
                        zend_hash_destroy(&ce->constants_table);
-                       if (ce->num_interfaces > 0) {
-                               if (!(ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
-                                       uint32_t i;
-
-                                       for (i = 0; i < ce->num_interfaces; i++) {
-                                               zend_string_release_ex(ce->interface_names[i].name, 0);
-                                               zend_string_release_ex(ce->interface_names[i].lc_name, 0);
-                                       }
-                               }
+                       if (ce->num_interfaces > 0 && (ce->ce_flags & ZEND_ACC_RESOLVED_INTERFACES)) {
                                efree(ce->interfaces);
                        }
-                       zend_string_release_ex(ce->info.user.filename, 0);
-                       if (ce->info.user.doc_comment) {
-                               zend_string_release_ex(ce->info.user.doc_comment, 0);
-                       }
-                       if (ce->attributes) {
-                               zend_hash_release(ce->attributes);
-                       }
-
-                       if (ce->num_traits > 0) {
-                               _destroy_zend_class_traits_info(ce);
-                       }
-
                        break;
                case ZEND_INTERNAL_CLASS:
                        if (ce->default_properties_table) {
index 1406fd45b68e60a2521512cde0663981bc147022..d3011da941e02a79563276c72a8b03cdf5fd199e 100644 (file)
@@ -333,13 +333,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
        }
 
        if (ce->num_interfaces) {
-               zend_class_name *interface_names;
-
-               if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
-                       interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
-                       memcpy(interface_names, ce->interface_names, sizeof(zend_class_name) * ce->num_interfaces);
-                       ce->interface_names = interface_names;
-               } else {
+               if (ce->ce_flags & ZEND_ACC_LINKED) {
                        zend_class_entry **interfaces = emalloc(sizeof(zend_class_entry*) * ce->num_interfaces);
                        uint32_t i;
 
@@ -367,50 +361,6 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
        zend_update_inherited_handler(__debugInfo);
        zend_update_inherited_handler(__serialize);
        zend_update_inherited_handler(__unserialize);
-
-/* 5.4 traits */
-       if (ce->num_traits) {
-               zend_class_name *trait_names = emalloc(sizeof(zend_class_name) * ce->num_traits);
-
-               memcpy(trait_names, ce->trait_names, sizeof(zend_class_name) * ce->num_traits);
-               ce->trait_names = trait_names;
-
-               if (ce->trait_aliases) {
-                       zend_trait_alias **trait_aliases;
-                       int i = 0;
-
-                       while (ce->trait_aliases[i]) {
-                               i++;
-                       }
-                       trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
-                       i = 0;
-                       while (ce->trait_aliases[i]) {
-                               trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
-                               memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
-                               i++;
-                       }
-                       trait_aliases[i] = NULL;
-                       ce->trait_aliases = trait_aliases;
-               }
-
-               if (ce->trait_precedences) {
-                       zend_trait_precedence **trait_precedences;
-                       int i = 0;
-
-                       while (ce->trait_precedences[i]) {
-                               i++;
-                       }
-                       trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
-                       i = 0;
-                       while (ce->trait_precedences[i]) {
-                               trait_precedences[i] = emalloc(sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
-                               memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence) + (ce->trait_precedences[i]->num_excludes - 1) * sizeof(zend_string*));
-                               i++;
-                       }
-                       trait_precedences[i] = NULL;
-                       ce->trait_precedences = trait_precedences;
-               }
-       }
 }
 
 static void zend_accel_function_hash_copy(HashTable *target, HashTable *source)
index 2f7194a7ca9c44c82af16b0f648af0262781c9c8..9bdba91639a6bbdca6a9574ca00d4537e9fbf99e 100644 (file)
@@ -806,6 +806,7 @@ static void zend_persist_class_entry(zval *zv)
                        ZCG(is_immutable_class) = 0;
                        ce = Z_PTR_P(zv) = zend_shared_memdup_arena_put(ce, sizeof(zend_class_entry));
                }
+               ce->ce_flags |= ZEND_ACC_CACHED;
                zend_accel_store_interned_string(ce->name);
                if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
                        zend_accel_store_interned_string(ce->parent_name);