From b70d4dc82da4e61ca28e83ee3d3f9a8db24094a1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Feb 2022 11:13:08 +0300 Subject: [PATCH] Free cached chunks when the requested memory limit is above real usage. --- Zend/zend_alloc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index ace032e5e72d5..960038920e7e0 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2669,7 +2669,19 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) ZEND_API zend_result zend_set_memory_limit(size_t memory_limit) { #if ZEND_MM_LIMIT - if (UNEXPECTED(memory_limit < AG(mm_heap)->real_size)) { + zend_mm_heap *heap = AG(mm_heap); + if (UNEXPECTED(memory_limit < heap->real_size)) { + if (memory_limit >= heap->real_size - heap->cached_chunks_count * ZEND_MM_CHUNK_SIZE) { + /* free some cached chunks to fit into new memory limit */ + do { + zend_mm_chunk *p = heap->cached_chunks; + heap->cached_chunks = p->next; + zend_mm_chunk_free(heap, p, ZEND_MM_CHUNK_SIZE); + heap->cached_chunks_count--; + heap->real_size -= ZEND_MM_CHUNK_SIZE; + } while (memory_limit < heap->real_size); + return SUCCESS; + } return FAILURE; } AG(mm_heap)->limit = memory_limit;