Skip to content

Commit 397f5cb

Browse files
committed
Fixed bug #75368 (mmap/munmap trashing on unlucky allocations)
1 parent a55af1e commit 397f5cb

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2017 PHP 7.0.26
44

5+
- Core:
6+
. Fixed bug #75368 (mmap/munmap trashing on unlucky allocations). (Nikita,
7+
Dmitry)
8+
59
- Exif:
610
. Fixed bug #75301 (Exif extension has built in revision version). (Peter
711
Kokot)

Zend/zend_alloc.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ struct _zend_mm_heap {
267267
int peak_chunks_count; /* peak number of allocated chunks for current request */
268268
int cached_chunks_count; /* number of cached chunks */
269269
double avg_chunks_count; /* average number of chunks allocated per request */
270+
int last_chunks_delete_boundary; /* numer of chunks after last deletion */
271+
int last_chunks_delete_count; /* number of deletion over the last boundary */
270272
#if ZEND_MM_CUSTOM
271273
union {
272274
struct {
@@ -1122,7 +1124,9 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_
11221124
chunk->next->prev = chunk->prev;
11231125
chunk->prev->next = chunk->next;
11241126
heap->chunks_count--;
1125-
if (heap->chunks_count + heap->cached_chunks_count < heap->avg_chunks_count + 0.1) {
1127+
if (heap->chunks_count + heap->cached_chunks_count < heap->avg_chunks_count + 0.1
1128+
|| (heap->chunks_count == heap->last_chunks_delete_boundary
1129+
&& heap->last_chunks_delete_count >= 4)) {
11261130
/* delay deletion */
11271131
heap->cached_chunks_count++;
11281132
chunk->next = heap->cached_chunks;
@@ -1131,6 +1135,14 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_
11311135
#if ZEND_MM_STAT || ZEND_MM_LIMIT
11321136
heap->real_size -= ZEND_MM_CHUNK_SIZE;
11331137
#endif
1138+
if (!heap->cached_chunks) {
1139+
if (heap->chunks_count != heap->last_chunks_delete_boundary) {
1140+
heap->last_chunks_delete_boundary = heap->chunks_count;
1141+
heap->last_chunks_delete_count = 0;
1142+
} else {
1143+
heap->last_chunks_delete_count++;
1144+
}
1145+
}
11341146
if (!heap->cached_chunks || chunk->num > heap->cached_chunks->num) {
11351147
zend_mm_chunk_free(heap, chunk, ZEND_MM_CHUNK_SIZE);
11361148
} else {
@@ -1864,6 +1876,8 @@ static zend_mm_heap *zend_mm_init(void)
18641876
heap->peak_chunks_count = 1;
18651877
heap->cached_chunks_count = 0;
18661878
heap->avg_chunks_count = 1.0;
1879+
heap->last_chunks_delete_boundary = 0;
1880+
heap->last_chunks_delete_count = 0;
18671881
#if ZEND_MM_STAT || ZEND_MM_LIMIT
18681882
heap->real_size = ZEND_MM_CHUNK_SIZE;
18691883
#endif
@@ -2279,6 +2293,8 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent)
22792293
p->map[0] = ZEND_MM_LRUN(ZEND_MM_FIRST_PAGE);
22802294
heap->chunks_count = 1;
22812295
heap->peak_chunks_count = 1;
2296+
heap->last_chunks_delete_boundary = 0;
2297+
heap->last_chunks_delete_count = 0;
22822298
#if ZEND_MM_STAT || ZEND_MM_LIMIT
22832299
heap->real_size = ZEND_MM_CHUNK_SIZE;
22842300
#endif
@@ -2811,6 +2827,8 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
28112827
heap->peak_chunks_count = 1;
28122828
heap->cached_chunks_count = 0;
28132829
heap->avg_chunks_count = 1.0;
2830+
heap->last_chunks_delete_boundary = 0;
2831+
heap->last_chunks_delete_count = 0;
28142832
#if ZEND_MM_STAT || ZEND_MM_LIMIT
28152833
heap->real_size = ZEND_MM_CHUNK_SIZE;
28162834
#endif

0 commit comments

Comments
 (0)