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.c62
1 files changed, 17 insertions, 45 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 2e0de26378..a7e3808e7c 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>
@@ -200,6 +201,10 @@ typedef struct _zend_mm_huge_list zend_mm_huge_list;
# define PTR_FMT "0x%0.8lx"
#endif
+#ifdef MAP_HUGETLB
+int zend_mm_use_huge_pages = 0;
+#endif
+
/*
* Memory is retrived from OS by chunks of fixed size 2MB.
* Inside chunk it's managed by pages of fixed size 4096B.
@@ -462,7 +467,7 @@ static void *zend_mm_mmap(size_t size)
void *ptr;
#ifdef MAP_HUGETLB
- if (size == ZEND_MM_CHUNK_SIZE) {
+ if (zend_mm_use_huge_pages && size == ZEND_MM_CHUNK_SIZE) {
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_HUGETLB, -1, 0);
if (ptr != MAP_FAILED) {
return ptr;
@@ -542,45 +547,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;
@@ -602,7 +568,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);
@@ -937,7 +903,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;
}
@@ -994,7 +960,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;
@@ -1858,7 +1824,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
@@ -2328,7 +2294,7 @@ ZEND_API int is_zend_mm(void)
#endif
}
-#if !ZEND_DEBUG && !defined(_WIN32)
+#if !ZEND_DEBUG && (!defined(_WIN32) || defined(__clang__))
#undef _emalloc
#if ZEND_MM_CUSTOM
@@ -2648,6 +2614,12 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
return;
}
#endif
+#ifdef MAP_HUGETLB
+ tmp = getenv("USE_ZEND_ALLOC_HUGE_PAGES");
+ if (tmp && zend_atoi(tmp, 0)) {
+ zend_mm_use_huge_pages = 1;
+ }
+#endif
ZEND_TSRMLS_CACHE_UPDATE();
alloc_globals->mm_heap = zend_mm_init();
}