Skip to content

Commit

Permalink
__builtin_memcpy/set_inline from clang usage introduction.
Browse files Browse the repository at this point in the history
no extra calls guaranteed during LLVM IR generation but works only on constants
unlike their non inline counterparts.
  • Loading branch information
devnexen committed Jun 19, 2022
1 parent eb29d6b commit 167cc14
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
29 changes: 29 additions & 0 deletions include/mimalloc-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,21 @@ bool _mi_page_is_valid(mi_page_t* page);
#define __has_builtin(x) 0
#endif

#if __has_builtin(__builtin_memcpy_inline)
#define _mi_memcpy_inline(x, y, s) __builtin_memcpy_inline(x, y, s)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
#define _mi_memcpy_inline(x, y, s) do { _Static_assert(__builtin_choose_expr(__builtin_constant_p(s), 1, 0), "`_mi_memcpy_inline` must be a constant integer"); memcpy(x, y, s); } while (0)
#else
#define _mi_memcpy_inline(x, y, s) memcpy(x, y, s)
#endif

#if __has_builtin(__builtin_memset_inline)
#define _mi_memset_inline(x, y, s) __builtin_memset_inline(x, y, s)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
#define _mi_memset_inline(x, y, s) do { _Static_assert(__builtin_choose_expr(__builtin_constant_p(s), 1, 0), "`_mi_memset_inline` must be a constant integer"); memset(x, y, s); } while (0)
#else
#define _mi_memset_inline(x, y, s) memset(x, y, s)
#endif

/* -----------------------------------------------------------
Error codes passed to `_mi_fatal_error`
Expand Down Expand Up @@ -975,6 +990,17 @@ static inline void _mi_memzero_aligned(void* dst, size_t n) {
void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE);
_mi_memzero(adst, n);
}

#define _mi_memcpy_inline_aligned(dst, src, n) \
mi_assert_internal(((uintptr_t)dst % MI_INTPTR_SIZE == 0) && ((uintptr_t)src % MI_INTPTR_SIZE == 0)); \
void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); \
const void* asrc = __builtin_assume_aligned(src, MI_INTPTR_SIZE); \
_mi_memcpy_inline(adst, asrc, n)

#define _mi_memzero_inline_aligned(dst, n) \
mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0); \
void* adst = __builtin_assume_aligned(dst, MI_INTPTR_SIZE); \
_mi_memzero_inline(adst, n)
#else
// Default fallback on `_mi_memcpy`
static inline void _mi_memcpy_aligned(void* dst, const void* src, size_t n) {
Expand All @@ -986,6 +1012,9 @@ static inline void _mi_memzero_aligned(void* dst, size_t n) {
mi_assert_internal((uintptr_t)dst % MI_INTPTR_SIZE == 0);
_mi_memzero(dst, n);
}

#define _mi_memcpy_inline_aligned(dst, src, n) _mi_memcpy_aligned(dst, src, n)
#define _mi_memzero_inline_aligned(dst, n) _mi_memzero_aligned(dst, n)
#endif


Expand Down
4 changes: 2 additions & 2 deletions src/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mi_decl_nodiscard mi_heap_t* mi_heap_new(void) {
mi_heap_t* bheap = mi_heap_get_backing();
mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode?
if (heap==NULL) return NULL;
_mi_memcpy_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t));
_mi_memcpy_inline_aligned(heap, &_mi_heap_empty, sizeof(mi_heap_t));
heap->tld = bheap->tld;
heap->thread_id = _mi_thread_id();
_mi_random_split(&bheap->random, &heap->random);
Expand All @@ -220,7 +220,7 @@ static void mi_heap_reset_pages(mi_heap_t* heap) {
#ifdef MI_MEDIUM_DIRECT
memset(&heap->pages_free_medium, 0, sizeof(heap->pages_free_medium));
#endif
_mi_memcpy_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));
_mi_memcpy_inline_aligned(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages));
heap->thread_delayed_free = NULL;
heap->page_count = 0;
}
Expand Down

0 comments on commit 167cc14

Please sign in to comment.