Skip to content

Commit 5db44e3

Browse files
committed
Fix tracked_realloc
We should only drop the information about the old allocation after checking the memory limit. This makes the code a bit more awkward...
1 parent 32315c2 commit 5db44e3

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

Zend/zend_alloc.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,16 +2705,11 @@ static zend_always_inline void tracked_add(zend_mm_heap *heap, void *ptr, size_t
27052705
zend_hash_index_add_new(heap->tracked_allocs, h, &size_zv);
27062706
}
27072707

2708-
static zend_always_inline size_t tracked_del(zend_mm_heap *heap, void *ptr) {
2709-
if (!ptr) {
2710-
return 0;
2711-
}
2712-
2708+
static zend_always_inline zval *tracked_get_size_zv(zend_mm_heap *heap, void *ptr) {
27132709
zend_ulong h = ((uintptr_t) ptr) >> ZEND_MM_ALIGNMENT_LOG2;
27142710
zval *size_zv = zend_hash_index_find(heap->tracked_allocs, h);
27152711
ZEND_ASSERT(size_zv && "Trying to free pointer not allocated through ZendMM");
2716-
zend_hash_del_bucket(heap->tracked_allocs, (Bucket *) size_zv);
2717-
return Z_LVAL_P(size_zv);
2712+
return size_zv;
27182713
}
27192714

27202715
static zend_always_inline void tracked_check_limit(zend_mm_heap *heap, size_t add_size) {
@@ -2743,18 +2738,35 @@ static void *tracked_malloc(size_t size)
27432738
}
27442739

27452740
static void tracked_free(void *ptr) {
2741+
if (!ptr) {
2742+
return;
2743+
}
2744+
27462745
zend_mm_heap *heap = AG(mm_heap);
2747-
heap->size -= tracked_del(heap, ptr);
2746+
zval *size_zv = tracked_get_size_zv(heap, ptr);
2747+
heap->size -= Z_LVAL_P(size_zv);
2748+
zend_hash_del_bucket(heap->tracked_allocs, (Bucket *) size_zv);
27482749
free(ptr);
27492750
}
27502751

27512752
static void *tracked_realloc(void *ptr, size_t new_size) {
27522753
zend_mm_heap *heap = AG(mm_heap);
2753-
size_t old_size = tracked_del(heap, ptr);
2754+
zval *old_size_zv = NULL;
2755+
size_t old_size = 0;
2756+
if (ptr) {
2757+
old_size_zv = tracked_get_size_zv(heap, ptr);
2758+
old_size = Z_LVAL_P(old_size_zv);
2759+
}
2760+
27542761
if (new_size > old_size) {
27552762
tracked_check_limit(heap, new_size - old_size);
27562763
}
27572764

2765+
/* Delete information about old allocation only after checking the memory limit. */
2766+
if (old_size_zv) {
2767+
zend_hash_del_bucket(heap->tracked_allocs, (Bucket *) old_size_zv);
2768+
}
2769+
27582770
ptr = __zend_realloc(ptr, new_size);
27592771
tracked_add(heap, ptr, new_size);
27602772
heap->size += new_size - old_size;

0 commit comments

Comments
 (0)