@@ -1746,6 +1746,32 @@ ZEND_API inheritance_status zend_verify_property_hook_variance(const zend_proper
1746
1746
return zend_perform_covariant_type_check (ce , prop_info -> type , ce , value_arg_info -> type );
1747
1747
}
1748
1748
1749
+ #ifdef ZEND_WIN32
1750
+ /* Hooked properties set get_iterator, which causes issues on Windows. Windows
1751
+ * attaches multiple processes to the same shm, with each process potentially
1752
+ * having different addresses to the corresponding get_iterator function due to
1753
+ * ASLR. This prevents us from caching the class.
1754
+ *
1755
+ * To at least cache the unlinked class, avoid early-binding on Windows, and set
1756
+ * get_iterator during inheritance. The linked class may not use inheritance
1757
+ * cache. */
1758
+ static void zend_link_hooked_object_iter (zend_class_entry * ce ) {
1759
+ if (!ce -> get_iterator && ce -> num_hooked_props ) {
1760
+ ce -> get_iterator = zend_hooked_object_get_iterator ;
1761
+ ce -> ce_flags &= ~ZEND_ACC_CACHEABLE ;
1762
+ if (CG (current_linking_class ) == ce ) {
1763
+ HashTable * ht = (HashTable * )ce -> inheritance_cache ;
1764
+ if (ht ) {
1765
+ zend_hash_destroy (ht );
1766
+ FREE_HASHTABLE (ht );
1767
+ ce -> inheritance_cache = NULL ;
1768
+ }
1769
+ CG (current_linking_class ) = NULL ;
1770
+ }
1771
+ }
1772
+ }
1773
+ #endif
1774
+
1749
1775
ZEND_API void zend_do_inheritance_ex (zend_class_entry * ce , zend_class_entry * parent_ce , bool checked ) /* {{{ */
1750
1776
{
1751
1777
zend_property_info * property_info ;
@@ -3544,6 +3570,10 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
3544
3570
orig_linking_class = CG (current_linking_class );
3545
3571
CG (current_linking_class ) = is_cacheable ? ce : NULL ;
3546
3572
3573
+ #ifdef ZEND_WIN32
3574
+ zend_link_hooked_object_iter (ce );
3575
+ #endif
3576
+
3547
3577
if (ce -> ce_flags & ZEND_ACC_ENUM ) {
3548
3578
/* Only register builtin enum methods during inheritance to avoid persisting them in
3549
3579
* opcache. */
0 commit comments