Skip to content

Commit cf14a3b

Browse files
committed
Do not create the opcache shm mapping too close to the end of the heap
Under some conditions we may create the opcache shm segment just after the heap, which prevents it from expanding. Memory allocators may fallback to mmap(), but this may confuse some (unidentified) code.
1 parent 5a726fd commit cf14a3b

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

ext/opcache/shared_alloc_mmap.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,21 @@ static void *find_prefered_mmap_base(size_t requested_size)
6666
* a segment directly preceding or following the heap is interpreted as heap memory, which
6767
* will result in an execheap violation for the JIT.
6868
* See https://bugzilla.kernel.org/show_bug.cgi?id=218258. */
69+
/* Also don't place the segment too close to the end of the heap, as
70+
* this can prevent it from expanding contiguously, which may confuse
71+
* some code (GH-13775). */
6972
bool heap_segment = strstr(buffer, "[heap]") != NULL;
7073
if (heap_segment) {
71-
uintptr_t start_base = start & ~(huge_page_size - 1);
72-
if (last_free_addr + requested_size >= start_base) {
73-
last_free_addr = ZEND_MM_ALIGNED_SIZE_EX(end + huge_page_size, huge_page_size);
74-
continue;
74+
if (last_candidate != (uintptr_t)MAP_FAILED) {
75+
uintptr_t start_base = start & ~(huge_page_size - 1);
76+
if (last_free_addr + requested_size >= start_base) {
77+
last_candidate = (uintptr_t)MAP_FAILED;
78+
}
7579
}
80+
/* The heap is located after the text segment, so once we find it
81+
* there is no chance of finding a better candidate that is close
82+
* enough of the text segment and also far enough from the heap. */
83+
break;
7684
}
7785
if ((uintptr_t)execute_ex >= start) {
7886
/* the current segment lays before PHP .text segment or PHP .text segment itself */

0 commit comments

Comments
 (0)