Created
November 17, 2021 15:04
-
-
Save dstogov/22404cf96ac1067899488edb3601954d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend_types.h b/Zend/zend_types.h | |
index 6f7fef32a0..151afadec2 100644 | |
--- a/Zend/zend_types.h | |
+++ b/Zend/zend_types.h | |
@@ -726,10 +726,25 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) { | |
/* Fast class cache */ | |
#define ZSTR_HAS_CE_CACHE(s) (GC_FLAGS(s) & IS_STR_CLASS_NAME_MAP_PTR) | |
-#define ZSTR_GET_CE_CACHE(s) \ | |
- (*(zend_class_entry **)ZEND_MAP_PTR_OFFSET2PTR(GC_REFCOUNT(s))) | |
-#define ZSTR_SET_CE_CACHE(s, ce) do { \ | |
- *((zend_class_entry **)ZEND_MAP_PTR_OFFSET2PTR(GC_REFCOUNT(s))) = ce; \ | |
+#define ZSTR_GET_CE_CACHE(s) ZSTR_GET_CE_CACHE_EX(s, 1) | |
+#define ZSTR_SET_CE_CACHE(s, ce) ZSTR_SET_CE_CACHE_EX(s, ce, 1) | |
+ | |
+#define ZSTR_VALID_CE_CACHE(s) EXPECTED((GC_REFCOUNT(s)-1)/sizeof(void *) < CG(map_ptr_last)) | |
+ | |
+#define ZSTR_GET_CE_CACHE_EX(s, validate) \ | |
+ ((!(validate) || ZSTR_VALID_CE_CACHE(s)) ? GET_CE_CACHE(GC_REFCOUNT(s)) : NULL) | |
+ | |
+#define ZSTR_SET_CE_CACHE_EX(s, ce, validate) do { \ | |
+ if (!(validate) || ZSTR_VALID_CE_CACHE(s)) { \ | |
+ SET_CE_CACHE(GC_REFCOUNT(s), ce); \ | |
+ } \ | |
+ } while (0) | |
+ | |
+#define GET_CE_CACHE(ce_cache) \ | |
+ (*(zend_class_entry **)ZEND_MAP_PTR_OFFSET2PTR(ce_cache)) | |
+ | |
+#define SET_CE_CACHE(ce_cache, ce) do { \ | |
+ *((zend_class_entry **)ZEND_MAP_PTR_OFFSET2PTR(ce_cache)) = ce; \ | |
} while (0) | |
/* Recursion protection macros must be used only for arrays and objects */ | |
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c | |
index 002ea3e5d2..28b458235c 100644 | |
--- a/ext/opcache/zend_accelerator_util_funcs.c | |
+++ b/ext/opcache/zend_accelerator_util_funcs.c | |
@@ -220,7 +220,7 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source) | |
if ((ce->ce_flags & ZEND_ACC_LINKED) | |
&& ZSTR_HAS_CE_CACHE(ce->name) | |
&& ZSTR_VAL(p->key)[0]) { | |
- ZSTR_SET_CE_CACHE(ce->name, ce); | |
+ ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0); | |
} | |
} | |
} | |
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c | |
index 0523f052eb..c438e6b38b 100644 | |
--- a/ext/opcache/zend_persist.c | |
+++ b/ext/opcache/zend_persist.c | |
@@ -889,7 +889,7 @@ zend_class_entry *zend_persist_class_entry(zend_class_entry *orig_ce) | |
if (!(ce->ce_flags & ZEND_ACC_CACHED)) { | |
if (ZSTR_HAS_CE_CACHE(ce->name)) { | |
- ZSTR_SET_CE_CACHE(ce->name, NULL); | |
+ ZSTR_SET_CE_CACHE_EX(ce->name, NULL, 0); | |
} | |
zend_accel_store_interned_string(ce->name); | |
if (!(ce->ce_flags & ZEND_ACC_ANON_CLASS) | |
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c | |
index e06d3ca672..4132a7e8aa 100644 | |
--- a/ext/opcache/ZendAccelerator.c | |
+++ b/ext/opcache/ZendAccelerator.c | |
@@ -2286,11 +2286,14 @@ static zend_class_entry* zend_accel_inheritance_cache_get(zend_class_entry *ce, | |
entry = zend_accel_inheritance_cache_find(entry, ce, parent, traits_and_interfaces, &needs_autoload); | |
if (entry) { | |
if (!needs_autoload) { | |
+ replay_warnings(entry->num_warnings, entry->warnings); | |
if (ZCSG(map_ptr_last) > CG(map_ptr_last)) { | |
zend_map_ptr_extend(ZCSG(map_ptr_last)); | |
} | |
- replay_warnings(entry->num_warnings, entry->warnings); | |
- return entry->ce; | |
+ ce = entry->ce; | |
+ ZEND_ASSERT(ZSTR_HAS_CE_CACHE(ce->name)); | |
+ ZSTR_SET_CE_CACHE_EX(ce->name, ce, 0); | |
+ return ce; | |
} | |
for (i = 0; i < entry->dependencies_count; i++) { | |
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c | |
index 3a4aaba0a3..55d67a5914 100644 | |
--- a/Zend/zend_inheritance.c | |
+++ b/Zend/zend_inheritance.c | |
@@ -2768,9 +2768,6 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string | |
} | |
zv = zend_hash_find_known_hash(CG(class_table), key); | |
Z_CE_P(zv) = ret; | |
- if (ZSTR_HAS_CE_CACHE(ret->name)) { | |
- ZSTR_SET_CE_CACHE(ret->name, ret); | |
- } | |
return ret; | |
} | |
@@ -2995,9 +2992,6 @@ ZEND_API zend_class_entry *zend_try_early_bind(zend_class_entry *ce, zend_class_ | |
if (UNEXPECTED(!register_early_bound_ce(delayed_early_binding, lcname, ret))) { | |
return NULL; | |
} | |
- if (ZSTR_HAS_CE_CACHE(ret->name)) { | |
- ZSTR_SET_CE_CACHE(ret->name, ret); | |
- } | |
return ret; | |
} | |
} else { | |
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c | |
index 3a107427f6..fed3ae1d29 100644 | |
--- a/Zend/zend_execute_API.c | |
+++ b/Zend/zend_execute_API.c | |
@@ -1062,10 +1062,12 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * | |
zval *zv; | |
zend_string *lc_name; | |
zend_string *autoload_name; | |
+ uint32_t ce_cache = 0; | |
- if (ZSTR_HAS_CE_CACHE(name)) { | |
- ce = ZSTR_GET_CE_CACHE(name); | |
- if (ce) { | |
+ if (ZSTR_HAS_CE_CACHE(name) && ZSTR_VALID_CE_CACHE(name)) { | |
+ ce_cache = GC_REFCOUNT(name); | |
+ ce = GET_CE_CACHE(ce_cache); | |
+ if (EXPECTED(ce)) { | |
return ce; | |
} | |
} | |
@@ -1106,9 +1108,9 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * | |
} | |
/* Don't populate CE_CACHE for mutable classes during compilation. | |
* The class may be freed while persisting. */ | |
- if (ZSTR_HAS_CE_CACHE(name) && | |
+ if (ce_cache && | |
(!CG(in_compilation) || (ce->ce_flags & ZEND_ACC_IMMUTABLE))) { | |
- ZSTR_SET_CE_CACHE(name, ce); | |
+ SET_CE_CACHE(ce_cache, ce); | |
} | |
return ce; | |
} | |
@@ -1164,8 +1166,8 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string * | |
} | |
if (ce) { | |
ZEND_ASSERT(!CG(in_compilation)); | |
- if (ZSTR_HAS_CE_CACHE(name)) { | |
- ZSTR_SET_CE_CACHE(name, ce); | |
+ if (ce_cache) { | |
+ SET_CE_CACHE(ce_cache, ce); | |
} | |
} | |
return ce; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment