summaryrefslogtreecommitdiff
path: root/include/mimalloc-internal.h
diff options
context:
space:
mode:
authorJim Huang <jserv.tw@gmail.com>2019-07-07 12:56:40 +0800
committerdaan <daanl@outlook.com>2019-07-23 14:59:49 -0700
commit8dba36bcecf33aaa743e75baf5996bfb9f898ead (patch)
treec824cec1d23f429108509ccaabb9946ff912bc8f /include/mimalloc-internal.h
parent46b11fa0a48ed34bb753470668bff5c6551dfab9 (diff)
Use checked unsigned multiplication extension of GCC/Clang
Most processors have carry flags which they set on addition overflow, so it is a good idea to access them whenever possible. Most of them also have widening multiply instructions that can be used to detect overflow of the non-widening version. Both GCC and Clang offer a way to detect an overflow for security critical applications. Reference: https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins
Diffstat (limited to 'include/mimalloc-internal.h')
-rw-r--r--include/mimalloc-internal.h11
1 files changed, 11 insertions, 0 deletions
diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h
index 1d380e8..cbed590 100644
--- a/include/mimalloc-internal.h
+++ b/include/mimalloc-internal.h
@@ -117,6 +117,9 @@ bool _mi_page_is_valid(mi_page_t* page);
#define mi_likely(x) (x)
#endif
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
#if defined(_MSC_VER)
#define mi_decl_noinline __declspec(noinline)
@@ -149,9 +152,17 @@ bool _mi_page_is_valid(mi_page_t* page);
// Overflow detecting multiply
#define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX)
static inline bool mi_mul_overflow(size_t size, size_t count, size_t* total) {
+#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5
+#if (MI_INTPTR_SIZE == 4)
+ return __builtin_umul_overflow(size, count, total);
+#else
+ return __builtin_umull_overflow(size, count, total);
+#endif
+#else /* __builtin_umul_overflow is unavailable */
*total = size * count;
return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW)
&& size > 0 && (SIZE_MAX / size) < count);
+#endif
}
// Align a byte size to a size in _machine words_,