3535# ifdef HAVE_UNISTD_H
3636# include <unistd.h>
3737# endif
38- # if defined(__linux__ ) && defined(HAVE_MEMFD_CREATE )
38+ # if defined(USE_MMAP ) || (defined( __linux__ ) && defined(HAVE_MEMFD_CREATE ) )
3939# include <sys/mman.h>
4040# endif
4141#endif
4242
43+ #if defined(USE_MMAP ) && !defined(ZEND_WIN32 )
44+ # if defined(MAP_ANON ) && !defined(MAP_ANONYMOUS )
45+ # define MAP_ANONYMOUS MAP_ANON
46+ # endif
47+
48+ static zend_always_inline bool zend_opcache_static_cache_force_startup_failure (void )
49+ {
50+ const char * value = getenv ("OPCACHE_STATIC_CACHE_FORCE_STARTUP_FAILURE" );
51+
52+ return value != NULL && value [0 ] != '\0' && value [0 ] != '0' ;
53+ }
54+
55+ static zend_always_inline bool zend_opcache_static_cache_requires_pre_request_storage (void )
56+ {
57+ return sapi_module .name != NULL && strcmp (sapi_module .name , "fpm-fcgi" ) == 0 ;
58+ }
59+
60+ static zend_always_inline void zend_opcache_static_cache_set_unavailable (const char * failure_reason , bool startup_failed )
61+ {
62+ zend_opcache_static_cache_context * context = zend_opcache_static_cache_active_context ();
63+ zend_opcache_static_cache_runtime * runtime = zend_opcache_static_cache_context_runtime (context );
64+
65+ runtime -> available = false;
66+ runtime -> startup_failed = startup_failed ;
67+ runtime -> backend_initialized = context -> storage .initialized ;
68+ runtime -> failure_reason = failure_reason ;
69+ }
70+
71+ static zend_always_inline void zend_opcache_static_cache_set_available (void )
72+ {
73+ zend_opcache_static_cache_context * context = zend_opcache_static_cache_active_context ();
74+ zend_opcache_static_cache_runtime * runtime = zend_opcache_static_cache_context_runtime (context );
75+
76+ runtime -> available = true;
77+ runtime -> startup_failed = false;
78+ runtime -> backend_initialized = context -> storage .initialized ;
79+ runtime -> failure_reason = NULL ;
80+ }
81+
82+ static zend_always_inline HashTable * * zend_opcache_static_cache_entry_locks_ptr_for_context (zend_opcache_static_cache_context * context )
83+ {
84+ return context == & zend_opcache_static_cache_pinned_context_state
85+ ? & zend_opcache_static_cache_pinned_entry_locks
86+ : & zend_opcache_static_cache_volatile_entry_locks
87+ ;
88+ }
89+
90+ static zend_always_inline uint32_t * zend_opcache_static_cache_entry_lock_counts_for_context (zend_opcache_static_cache_context * context )
91+ {
92+ return context == & zend_opcache_static_cache_pinned_context_state
93+ ? zend_opcache_static_cache_pinned_entry_lock_counts
94+ : zend_opcache_static_cache_volatile_entry_lock_counts
95+ ;
96+ }
97+
98+ static zend_always_inline uint32_t zend_opcache_static_cache_entry_lock_stripe (zend_string * key )
99+ {
100+ return (uint32_t ) (zend_string_hash_val (key ) % ZEND_OPCACHE_STATIC_CACHE_ENTRY_LOCK_STRIPES );
101+ }
102+
103+ static zend_always_inline uint32_t zend_opcache_static_cache_used_end_offset_locked (const zend_opcache_static_cache_header * header )
104+ {
105+ return header -> data_offset + header -> next_free ;
106+ }
107+
108+ static zend_always_inline bool zend_opcache_static_cache_payload_size_to_block_size (size_t size , uint32_t * block_size )
109+ {
110+ size_t aligned_size ;
111+
112+ if (size == 0 || size > UINT32_MAX - sizeof (zend_opcache_static_cache_block )) {
113+ return false;
114+ }
115+
116+ aligned_size = ZEND_ALIGNED_SIZE (sizeof (zend_opcache_static_cache_block ) + size );
117+ if (aligned_size > UINT32_MAX ) {
118+ return false;
119+ }
120+
121+ * block_size = (uint32_t ) aligned_size ;
122+
123+ return true;
124+ }
125+
126+ static zend_always_inline bool zend_opcache_static_cache_offset_in_block (uint32_t offset , uint32_t block_offset , uint32_t block_size )
127+ {
128+ return offset >= block_offset + sizeof (zend_opcache_static_cache_block ) && offset < block_offset + block_size ;
129+ }
130+
43131#ifdef ZEND_WIN32
44132# define ZEND_OPCACHE_STATIC_CACHE_WIN32_MAPPING_PREFIX_SIZE (2 * sizeof(void *))
45133# define ZEND_OPCACHE_STATIC_CACHE_WIN32_MAPPING_NAME "ZendOPcache.StaticCache.SharedMemoryArea"
@@ -53,6 +141,80 @@ typedef struct _zend_opcache_static_cache_win32_segment {
53141 size_t mapping_size ;
54142} zend_opcache_static_cache_win32_segment ;
55143
144+ static inline bool zend_opcache_static_cache_win32_set_segment (
145+ zend_opcache_static_cache_win32_segment * segment ,
146+ HANDLE memfile ,
147+ void * mapping_base ,
148+ size_t mapping_size ,
149+ size_t requested_size
150+ )
151+ {
152+ segment -> memfile = memfile ;
153+ segment -> mapping_base = mapping_base ;
154+ segment -> mapping_size = mapping_size ;
155+ segment -> segment .p = (char * ) mapping_base + ZEND_OPCACHE_STATIC_CACHE_WIN32_MAPPING_PREFIX_SIZE ;
156+ segment -> segment .pos = 0 ;
157+ segment -> segment .size = requested_size ;
158+
159+ return true;
160+ }
161+ #endif
162+
163+ static int zend_opcache_static_cache_mmap_create_segments (
164+ size_t requested_size ,
165+ zend_shared_segment * * * shared_segments_p ,
166+ int * shared_segments_count ,
167+ const char * * error_in
168+ )
169+ {
170+ zend_shared_segment * segment ;
171+ void * mapping ;
172+
173+ mapping = mmap (NULL , requested_size , PROT_READ | PROT_WRITE , MAP_SHARED | MAP_ANONYMOUS , -1 , 0 );
174+ if (mapping == MAP_FAILED ) {
175+ * error_in = "mmap" ;
176+ return ALLOC_FAILURE ;
177+ }
178+
179+ * shared_segments_count = 1 ;
180+ * shared_segments_p = (zend_shared_segment * * ) calloc (1 , sizeof (zend_shared_segment * ) + sizeof (zend_shared_segment ));
181+ if (* shared_segments_p == NULL ) {
182+ munmap (mapping , requested_size );
183+ * error_in = "calloc" ;
184+ return ALLOC_FAILURE ;
185+ }
186+
187+ segment = (zend_shared_segment * ) ((char * ) * shared_segments_p + sizeof (zend_shared_segment * ));
188+ (* shared_segments_p )[0 ] = segment ;
189+
190+ segment -> p = mapping ;
191+ segment -> pos = 0 ;
192+ segment -> size = requested_size ;
193+ segment -> end = requested_size ;
194+
195+ return ALLOC_SUCCESS ;
196+ }
197+
198+ static int zend_opcache_static_cache_mmap_detach_segment (zend_shared_segment * shared_segment )
199+ {
200+ munmap (shared_segment -> p , shared_segment -> size );
201+
202+ return 0 ;
203+ }
204+
205+ static size_t zend_opcache_static_cache_mmap_segment_type_size (void )
206+ {
207+ return sizeof (zend_shared_segment );
208+ }
209+
210+ static const zend_shared_memory_handlers zend_opcache_static_cache_mmap_handlers = {
211+ zend_opcache_static_cache_mmap_create_segments ,
212+ zend_opcache_static_cache_mmap_detach_segment ,
213+ zend_opcache_static_cache_mmap_segment_type_size
214+ };
215+ #endif
216+
217+ #ifdef ZEND_WIN32
56218static void zend_opcache_static_cache_win32_create_name (char * buffer , size_t buffer_size , const char * name , size_t unique_id )
57219{
58220 zend_opcache_static_cache_context * context = zend_opcache_static_cache_active_context ();
@@ -71,24 +233,6 @@ static void zend_opcache_static_cache_win32_create_name(char *buffer, size_t buf
71233 );
72234}
73235
74- static bool zend_opcache_static_cache_win32_set_segment (
75- zend_opcache_static_cache_win32_segment * segment ,
76- HANDLE memfile ,
77- void * mapping_base ,
78- size_t mapping_size ,
79- size_t requested_size
80- )
81- {
82- segment -> memfile = memfile ;
83- segment -> mapping_base = mapping_base ;
84- segment -> mapping_size = mapping_size ;
85- segment -> segment .p = (char * ) mapping_base + ZEND_OPCACHE_STATIC_CACHE_WIN32_MAPPING_PREFIX_SIZE ;
86- segment -> segment .pos = 0 ;
87- segment -> segment .size = requested_size ;
88-
89- return true;
90- }
91-
92236static int zend_opcache_static_cache_win32_reattach_segment (
93237 zend_opcache_static_cache_win32_segment * segment ,
94238 HANDLE memfile ,
@@ -357,8 +501,8 @@ static const zend_shared_memory_handlers zend_opcache_static_cache_win32_handler
357501#endif
358502
359503static const zend_shared_memory_handler_entry zend_opcache_static_cache_handler_table [] = {
360- #ifdef USE_MMAP
361- { "mmap" , & zend_alloc_mmap_handlers },
504+ #if defined( USE_MMAP ) && ! defined ( ZEND_WIN32 )
505+ { "mmap" , & zend_opcache_static_cache_mmap_handlers },
362506#endif
363507#ifdef USE_SHM
364508 { "shm" , & zend_alloc_shm_handlers },
@@ -379,41 +523,7 @@ static ZEND_EXT_TLS bool zend_opcache_static_cache_entry_locks_process_is_fork_c
379523#endif
380524#endif
381525
382- static zend_always_inline bool zend_opcache_static_cache_force_startup_failure (void )
383- {
384- const char * value = getenv ("OPCACHE_STATIC_CACHE_FORCE_STARTUP_FAILURE" );
385-
386- return value != NULL && value [0 ] != '\0' && value [0 ] != '0' ;
387- }
388-
389- static zend_always_inline bool zend_opcache_static_cache_requires_pre_request_storage (void )
390- {
391- return sapi_module .name != NULL && strcmp (sapi_module .name , "fpm-fcgi" ) == 0 ;
392- }
393-
394- static zend_always_inline void zend_opcache_static_cache_set_unavailable (const char * failure_reason , bool startup_failed )
395- {
396- zend_opcache_static_cache_context * context = zend_opcache_static_cache_active_context ();
397- zend_opcache_static_cache_runtime * runtime = zend_opcache_static_cache_context_runtime (context );
398-
399- runtime -> available = false;
400- runtime -> startup_failed = startup_failed ;
401- runtime -> backend_initialized = context -> storage .initialized ;
402- runtime -> failure_reason = failure_reason ;
403- }
404-
405- static zend_always_inline void zend_opcache_static_cache_set_available (void )
406- {
407- zend_opcache_static_cache_context * context = zend_opcache_static_cache_active_context ();
408- zend_opcache_static_cache_runtime * runtime = zend_opcache_static_cache_context_runtime (context );
409-
410- runtime -> available = true;
411- runtime -> startup_failed = false;
412- runtime -> backend_initialized = context -> storage .initialized ;
413- runtime -> failure_reason = NULL ;
414- }
415-
416- static zend_always_inline void zend_opcache_static_cache_cleanup_segments (const zend_shared_memory_handlers * handler , zend_shared_segment * * segments , int segment_count )
526+ static void zend_opcache_static_cache_cleanup_segments (const zend_shared_memory_handlers * handler , zend_shared_segment * * segments , int segment_count )
417527{
418528 int index ;
419529
@@ -869,27 +979,6 @@ static void zend_opcache_static_cache_unlock_impl(void)
869979}
870980#endif
871981
872- static HashTable * * zend_opcache_static_cache_entry_locks_ptr_for_context (zend_opcache_static_cache_context * context )
873- {
874- return context == & zend_opcache_static_cache_pinned_context_state
875- ? & zend_opcache_static_cache_pinned_entry_locks
876- : & zend_opcache_static_cache_volatile_entry_locks
877- ;
878- }
879-
880- static uint32_t * zend_opcache_static_cache_entry_lock_counts_for_context (zend_opcache_static_cache_context * context )
881- {
882- return context == & zend_opcache_static_cache_pinned_context_state
883- ? zend_opcache_static_cache_pinned_entry_lock_counts
884- : zend_opcache_static_cache_volatile_entry_lock_counts
885- ;
886- }
887-
888- static uint32_t zend_opcache_static_cache_entry_lock_stripe (zend_string * key )
889- {
890- return (uint32_t ) (zend_string_hash_val (key ) % ZEND_OPCACHE_STATIC_CACHE_ENTRY_LOCK_STRIPES );
891- }
892-
893982#if defined(ZTS ) && !defined(ZEND_WIN32 )
894983static void zend_opcache_static_cache_entry_locks_reinit_after_fork (zend_opcache_static_cache_storage * storage )
895984{
@@ -1395,11 +1484,6 @@ static uint32_t zend_opcache_static_cache_calculate_capacity(size_t size)
13951484 return (uint32_t ) capacity ;
13961485}
13971486
1398- static zend_always_inline uint32_t zend_opcache_static_cache_used_end_offset_locked (const zend_opcache_static_cache_header * header )
1399- {
1400- return header -> data_offset + header -> next_free ;
1401- }
1402-
14031487static void zend_opcache_static_cache_free_list_remove_locked (zend_opcache_static_cache_header * header , uint32_t block_offset )
14041488{
14051489 zend_opcache_static_cache_block * block = zend_opcache_static_cache_block_ptr (block_offset );
@@ -1594,29 +1678,6 @@ static bool zend_opcache_static_cache_startup_storage(void)
15941678 return true;
15951679}
15961680
1597- static zend_always_inline bool zend_opcache_static_cache_payload_size_to_block_size (size_t size , uint32_t * block_size )
1598- {
1599- size_t aligned_size ;
1600-
1601- if (size == 0 || size > UINT32_MAX - sizeof (zend_opcache_static_cache_block )) {
1602- return false;
1603- }
1604-
1605- aligned_size = ZEND_ALIGNED_SIZE (sizeof (zend_opcache_static_cache_block ) + size );
1606- if (aligned_size > UINT32_MAX ) {
1607- return false;
1608- }
1609-
1610- * block_size = (uint32_t ) aligned_size ;
1611-
1612- return true;
1613- }
1614-
1615- static zend_always_inline bool zend_opcache_static_cache_offset_in_block (uint32_t offset , uint32_t block_offset , uint32_t block_size )
1616- {
1617- return offset >= block_offset + sizeof (zend_opcache_static_cache_block ) && offset < block_offset + block_size ;
1618- }
1619-
16201681static bool zend_opcache_static_cache_block_is_movable_locked (
16211682 zend_opcache_static_cache_header * header ,
16221683 uint32_t block_offset ,
0 commit comments