summaryrefslogtreecommitdiff
path: root/Zend/zend_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_alloc.c')
-rw-r--r--Zend/zend_alloc.c104
1 files changed, 30 insertions, 74 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 1876559317..ed7575d256 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -58,6 +58,7 @@
#include "zend_globals.h"
#include "zend_operators.h"
#include "zend_multiply.h"
+#include "zend_bitset.h"
#ifdef HAVE_SIGNAL_H
# include <signal.h>
@@ -192,14 +193,6 @@ typedef struct _zend_mm_free_slot zend_mm_free_slot;
typedef struct _zend_mm_chunk zend_mm_chunk;
typedef struct _zend_mm_huge_list zend_mm_huge_list;
-#ifdef _WIN64
-# define PTR_FMT "0x%0.16I64x"
-#elif SIZEOF_LONG == 8
-# define PTR_FMT "0x%0.16lx"
-#else
-# define PTR_FMT "0x%0.8lx"
-#endif
-
#ifdef MAP_HUGETLB
int zend_mm_use_huge_pages = 0;
#endif
@@ -287,9 +280,9 @@ struct _zend_mm_chunk {
zend_mm_heap *heap;
zend_mm_chunk *next;
zend_mm_chunk *prev;
- int free_pages; /* number of free pages */
- int free_tail; /* number of free pages at the end of chunk */
- int num;
+ uint32_t free_pages; /* number of free pages */
+ uint32_t free_tail; /* number of free pages at the end of chunk */
+ uint32_t num;
char reserve[64 - (sizeof(void*) * 3 + sizeof(int) * 3)];
zend_mm_heap heap_slot; /* used only in main chunk */
zend_mm_page_map free_map; /* 512 bits or 64 bytes */
@@ -325,17 +318,17 @@ struct _zend_mm_huge_list {
((void*)(((zend_mm_page*)(chunk)) + (page_num)))
#define _BIN_DATA_SIZE(num, size, elements, pages, x, y) size,
-static const unsigned int bin_data_size[] = {
+static const uint32_t bin_data_size[] = {
ZEND_MM_BINS_INFO(_BIN_DATA_SIZE, x, y)
};
#define _BIN_DATA_ELEMENTS(num, size, elements, pages, x, y) elements,
-static const int bin_elements[] = {
+static const uint32_t bin_elements[] = {
ZEND_MM_BINS_INFO(_BIN_DATA_ELEMENTS, x, y)
};
#define _BIN_DATA_PAGES(num, size, elements, pages, x, y) pages,
-static const int bin_pages[] = {
+static const uint32_t bin_pages[] = {
ZEND_MM_BINS_INFO(_BIN_DATA_PAGES, x, y)
};
@@ -546,45 +539,6 @@ static zend_always_inline int zend_mm_bitset_nts(zend_mm_bitset bitset)
#endif
}
-/* number of trailing zero bits (0x01 -> 1; 0x40 -> 6; 0x00 -> LEN) */
-static zend_always_inline int zend_mm_bitset_ntz(zend_mm_bitset bitset)
-{
-#if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) && SIZEOF_ZEND_LONG == SIZEOF_LONG && defined(PHP_HAVE_BUILTIN_CTZL)
- return __builtin_ctzl(bitset);
-#elif (defined(__GNUC__) || __has_builtin(__builtin_ctzll)) && defined(PHP_HAVE_BUILTIN_CTZLL)
- return __builtin_ctzll(bitset);
-#elif defined(_WIN32)
- unsigned long index;
-
-#if defined(_WIN64)
- if (!BitScanForward64(&index, bitset)) {
-#else
- if (!BitScanForward(&index, bitset)) {
-#endif
- /* undefined behavior */
- return 32;
- }
-
- return (int)index;
-#else
- int n;
-
- if (bitset == (zend_mm_bitset)0) return ZEND_MM_BITSET_LEN;
-
- n = 1;
-#if SIZEOF_ZEND_LONG == 8
- if (sizeof(zend_mm_bitset) == 8) {
- if ((bitset & 0xffffffff) == 0) {n += 32; bitset = bitset >> Z_UL(32);}
- }
-#endif
- if ((bitset & 0x0000ffff) == 0) {n += 16; bitset = bitset >> 16;}
- if ((bitset & 0x000000ff) == 0) {n += 8; bitset = bitset >> 8;}
- if ((bitset & 0x0000000f) == 0) {n += 4; bitset = bitset >> 4;}
- if ((bitset & 0x00000003) == 0) {n += 2; bitset = bitset >> 2;}
- return n - (bitset & 1);
-#endif
-}
-
static zend_always_inline int zend_mm_bitset_find_zero(zend_mm_bitset *bitset, int size)
{
int i = 0;
@@ -606,7 +560,7 @@ static zend_always_inline int zend_mm_bitset_find_one(zend_mm_bitset *bitset, in
do {
zend_mm_bitset tmp = bitset[i];
if (tmp != 0) {
- return i * ZEND_MM_BITSET_LEN + zend_mm_bitset_ntz(tmp);
+ return i * ZEND_MM_BITSET_LEN + zend_ulong_ntz(tmp);
}
i++;
} while (i < size);
@@ -890,13 +844,13 @@ static void zend_mm_change_huge_block_size(zend_mm_heap *heap, void *ptr, size_t
/**************/
#if ZEND_DEBUG
-static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
+static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
#else
-static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
+static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
#endif
{
zend_mm_chunk *chunk = heap->main_chunk;
- int page_num, len;
+ uint32_t page_num, len;
while (1) {
if (UNEXPECTED(chunk->free_pages < pages_count)) {
@@ -941,7 +895,7 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_L
tmp = *(bitset++);
}
/* find first 1 bit */
- len = (i + zend_mm_bitset_ntz(tmp)) - page_num;
+ len = (i + zend_ulong_ntz(tmp)) - page_num;
if (len >= pages_count) {
goto found;
}
@@ -952,11 +906,11 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_L
} else {
/* Best-Fit Search */
int best = -1;
- int best_len = ZEND_MM_PAGES;
- int free_tail = chunk->free_tail;
+ uint32_t best_len = ZEND_MM_PAGES;
+ uint32_t free_tail = chunk->free_tail;
zend_mm_bitset *bitset = chunk->free_map;
zend_mm_bitset tmp = *(bitset++);
- int i = 0;
+ uint32_t i = 0;
while (1) {
/* skip allocated blocks */
@@ -998,7 +952,7 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, int pages_count ZEND_FILE_L
tmp = *(bitset++);
}
/* find first 1 bit */
- len = i + zend_mm_bitset_ntz(tmp) - page_num;
+ len = i + zend_ulong_ntz(tmp) - page_num;
if (len >= pages_count) {
if (len == pages_count) {
goto found;
@@ -1131,7 +1085,7 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_
}
}
-static zend_always_inline void zend_mm_free_pages_ex(zend_mm_heap *heap, zend_mm_chunk *chunk, int page_num, int pages_count, int free_chunk)
+static zend_always_inline void zend_mm_free_pages_ex(zend_mm_heap *heap, zend_mm_chunk *chunk, uint32_t page_num, uint32_t pages_count, int free_chunk)
{
chunk->free_pages += pages_count;
zend_mm_bitset_reset_range(chunk->free_map, page_num, pages_count);
@@ -1224,7 +1178,7 @@ static zend_always_inline int zend_mm_small_size_to_bin(size_t size)
#define ZEND_MM_SMALL_SIZE_TO_BIN(size) zend_mm_small_size_to_bin(size)
-static zend_never_inline void *zend_mm_alloc_small_slow(zend_mm_heap *heap, int bin_num ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
+static zend_never_inline void *zend_mm_alloc_small_slow(zend_mm_heap *heap, uint32_t bin_num ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
{
zend_mm_chunk *chunk;
int page_num;
@@ -1245,7 +1199,8 @@ static zend_never_inline void *zend_mm_alloc_small_slow(zend_mm_heap *heap, int
page_num = ZEND_MM_ALIGNED_OFFSET(bin, ZEND_MM_CHUNK_SIZE) / ZEND_MM_PAGE_SIZE;
chunk->map[page_num] = ZEND_MM_SRUN(bin_num);
if (bin_pages[bin_num] > 1) {
- int i = 1;
+ uint32_t i = 1;
+
do {
chunk->map[page_num+i] = ZEND_MM_NRUN(bin_num, i);
i++;
@@ -1862,7 +1817,7 @@ static zend_mm_heap *zend_mm_init(void)
heap->peak = 0;
#endif
#if ZEND_MM_LIMIT
- heap->limit = (Z_L(-1) >> Z_L(1));
+ heap->limit = ((size_t)Z_L(-1) >> (size_t)Z_L(1));
heap->overflow = 0;
#endif
#if ZEND_MM_CUSTOM
@@ -1882,7 +1837,8 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
size_t page_offset;
int page_num;
zend_mm_page_info info;
- int i, has_free_pages, free_counter;
+ uint32_t i, free_counter;
+ int has_free_pages;
size_t collected = 0;
#if ZEND_MM_CUSTOM
@@ -1993,7 +1949,7 @@ ZEND_API size_t zend_mm_gc(zend_mm_heap *heap)
/* Leak detection */
/******************/
-static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, int i, int j, zend_leak_info *leak)
+static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, uint32_t i, uint32_t j, zend_leak_info *leak)
{
int empty = 1;
zend_long count = 0;
@@ -2020,7 +1976,7 @@ static zend_long zend_mm_find_leaks_small(zend_mm_chunk *p, int i, int j, zend_l
return count;
}
-static zend_long zend_mm_find_leaks(zend_mm_heap *heap, zend_mm_chunk *p, int i, zend_leak_info *leak)
+static zend_long zend_mm_find_leaks(zend_mm_heap *heap, zend_mm_chunk *p, uint32_t i, zend_leak_info *leak)
{
zend_long count = 0;
@@ -2078,7 +2034,7 @@ static void zend_mm_check_leaks(zend_mm_heap *heap)
zend_leak_info leak;
zend_long repeated = 0;
uint32_t total = 0;
- int i, j;
+ uint32_t i, j;
/* find leaked huge blocks and free them */
list = heap->huge_list;
@@ -2418,7 +2374,7 @@ ZEND_API void ZEND_FASTCALL _efree_large(void *ptr, size_t size)
size_t page_offset = ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE);
zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE);
int page_num = page_offset / ZEND_MM_PAGE_SIZE;
- int pages_count = ZEND_MM_ALIGNED_SIZE_EX(size, ZEND_MM_PAGE_SIZE) / ZEND_MM_PAGE_SIZE;
+ uint32_t pages_count = ZEND_MM_ALIGNED_SIZE_EX(size, ZEND_MM_PAGE_SIZE) / ZEND_MM_PAGE_SIZE;
ZEND_MM_CHECK(chunk->heap == AG(mm_heap) && ZEND_MM_ALIGNED_OFFSET(page_offset, ZEND_MM_PAGE_SIZE) == 0, "zend_mm_heap corrupted");
ZEND_ASSERT(chunk->map[page_num] & ZEND_MM_IS_LRUN);
@@ -2553,7 +2509,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_
length = strlen(s);
if (UNEXPECTED(length + 1 == 0)) {
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
}
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
@@ -2568,7 +2524,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI
char *p;
if (UNEXPECTED(length + 1 == 0)) {
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
}
p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
if (UNEXPECTED(p == NULL)) {
@@ -2585,7 +2541,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length)
char *p;
if (UNEXPECTED(length + 1 == 0)) {
- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", 1, length, 1);
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length);
}
p = (char *) malloc(length + 1);
if (UNEXPECTED(p == NULL)) {