Skip to content

Commit 715acc0

Browse files
committed
mark assert_fail as cold and noreturn; move assert to internal.h (see issue #1091, and python/cpython#134586)
1 parent 3e32b4c commit 715acc0

File tree

3 files changed

+67
-46
lines changed

3 files changed

+67
-46
lines changed

include/mimalloc/internal.h

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ terms of the MIT license. A copy of the license can be found in the file
88
#ifndef MIMALLOC_INTERNAL_H
99
#define MIMALLOC_INTERNAL_H
1010

11-
1211
// --------------------------------------------------------------------------
1312
// This file contains the internal API's of mimalloc and various utility
1413
// functions and macros.
@@ -17,6 +16,11 @@ terms of the MIT license. A copy of the license can be found in the file
1716
#include "types.h"
1817
#include "track.h"
1918

19+
20+
// --------------------------------------------------------------------------
21+
// Compiler defines
22+
// --------------------------------------------------------------------------
23+
2024
#if (MI_DEBUG>0)
2125
#define mi_trace_message(...) _mi_trace_message(__VA_ARGS__)
2226
#else
@@ -30,38 +34,70 @@ terms of the MIT license. A copy of the license can be found in the file
3034
#define mi_decl_noinline __declspec(noinline)
3135
#define mi_decl_thread __declspec(thread)
3236
#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE))
37+
#define mi_decl_noreturn __declspec(noreturn)
3338
#define mi_decl_weak
3439
#define mi_decl_hidden
40+
#define mi_decl_cold
3541
#elif (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__clang__) // includes clang and icc
3642
#define mi_decl_noinline __attribute__((noinline))
3743
#define mi_decl_thread __thread
3844
#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE)))
45+
#define mi_decl_noreturn __attribute__((noreturn))
3946
#define mi_decl_weak __attribute__((weak))
4047
#define mi_decl_hidden __attribute__((visibility("hidden")))
48+
#if (__GNUC__ >= 4) || defined(__clang__)
49+
#define mi_decl_cold __attribute__((cold))
50+
#else
51+
#define mi_decl_cold
52+
#endif
4153
#elif __cplusplus >= 201103L // c++11
4254
#define mi_decl_noinline
4355
#define mi_decl_thread thread_local
4456
#define mi_decl_cache_align alignas(MI_CACHE_LINE)
57+
#define mi_decl_noreturn [[noreturn]]
4558
#define mi_decl_weak
4659
#define mi_decl_hidden
60+
#define mi_decl_cold
4761
#else
4862
#define mi_decl_noinline
4963
#define mi_decl_thread __thread // hope for the best :-)
5064
#define mi_decl_cache_align
65+
#define mi_decl_noreturn
5166
#define mi_decl_weak
5267
#define mi_decl_hidden
68+
#define mi_decl_cold
5369
#endif
5470

55-
#if defined(__EMSCRIPTEN__) && !defined(__wasi__)
56-
#define __wasi__
71+
#if defined(__GNUC__) || defined(__clang__)
72+
#define mi_unlikely(x) (__builtin_expect(!!(x),false))
73+
#define mi_likely(x) (__builtin_expect(!!(x),true))
74+
#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
75+
#define mi_unlikely(x) (x) [[unlikely]]
76+
#define mi_likely(x) (x) [[likely]]
77+
#else
78+
#define mi_unlikely(x) (x)
79+
#define mi_likely(x) (x)
80+
#endif
81+
82+
#ifndef __has_builtin
83+
#define __has_builtin(x) 0
5784
#endif
5885

5986
#if defined(__cplusplus)
60-
#define mi_decl_externc extern "C"
87+
#define mi_decl_externc extern "C"
6188
#else
6289
#define mi_decl_externc
6390
#endif
6491

92+
#if defined(__EMSCRIPTEN__) && !defined(__wasi__)
93+
#define __wasi__
94+
#endif
95+
96+
97+
// --------------------------------------------------------------------------
98+
// Internal functions
99+
// --------------------------------------------------------------------------
100+
65101
// "libc.c"
66102
#include <stdarg.h>
67103
int _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);
@@ -256,26 +292,6 @@ bool _mi_page_is_valid(mi_page_t* page);
256292
#endif
257293

258294

259-
// ------------------------------------------------------
260-
// Branches
261-
// ------------------------------------------------------
262-
263-
#if defined(__GNUC__) || defined(__clang__)
264-
#define mi_unlikely(x) (__builtin_expect(!!(x),false))
265-
#define mi_likely(x) (__builtin_expect(!!(x),true))
266-
#elif (defined(__cplusplus) && (__cplusplus >= 202002L)) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
267-
#define mi_unlikely(x) (x) [[unlikely]]
268-
#define mi_likely(x) (x) [[likely]]
269-
#else
270-
#define mi_unlikely(x) (x)
271-
#define mi_likely(x) (x)
272-
#endif
273-
274-
#ifndef __has_builtin
275-
#define __has_builtin(x) 0
276-
#endif
277-
278-
279295
/* -----------------------------------------------------------
280296
Error codes passed to `_mi_fatal_error`
281297
All are recoverable but EFAULT is a serious error and aborts by default in secure mode.
@@ -300,6 +316,32 @@ bool _mi_page_is_valid(mi_page_t* page);
300316
#endif
301317

302318

319+
// ------------------------------------------------------
320+
// Assertions
321+
// ------------------------------------------------------
322+
323+
#if (MI_DEBUG)
324+
// use our own assertion to print without memory allocation
325+
mi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func) mi_attr_noexcept;
326+
#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__))
327+
#else
328+
#define mi_assert(x)
329+
#endif
330+
331+
#if (MI_DEBUG>1)
332+
#define mi_assert_internal mi_assert
333+
#else
334+
#define mi_assert_internal(x)
335+
#endif
336+
337+
#if (MI_DEBUG>2)
338+
#define mi_assert_expensive mi_assert
339+
#else
340+
#define mi_assert_expensive(x)
341+
#endif
342+
343+
344+
303345
/* -----------------------------------------------------------
304346
Inlined definitions
305347
----------------------------------------------------------- */

include/mimalloc/types.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,6 @@ struct mi_tld_s {
574574
};
575575

576576

577-
578577
// ------------------------------------------------------
579578
// Debug
580579
// ------------------------------------------------------
@@ -589,26 +588,6 @@ struct mi_tld_s {
589588
#define MI_DEBUG_PADDING (0xDE)
590589
#endif
591590

592-
#if (MI_DEBUG)
593-
// use our own assertion to print without memory allocation
594-
void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func );
595-
#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__))
596-
#else
597-
#define mi_assert(x)
598-
#endif
599-
600-
#if (MI_DEBUG>1)
601-
#define mi_assert_internal mi_assert
602-
#else
603-
#define mi_assert_internal(x)
604-
#endif
605-
606-
#if (MI_DEBUG>2)
607-
#define mi_assert_expensive mi_assert
608-
#else
609-
#define mi_assert_expensive(x)
610-
#endif
611-
612591

613592
// ------------------------------------------------------
614593
// Statistics

src/options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ void _mi_warning_message(const char* fmt, ...) {
525525

526526

527527
#if MI_DEBUG
528-
void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) {
528+
mi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) mi_attr_noexcept {
529529
_mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion);
530530
abort();
531531
}

0 commit comments

Comments
 (0)