Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ project(libmimalloc C CXX)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

option(MI_CRAN_COMPLIANT "Provide support for compliance with the Comprehensive R-Archive Network (CRAN) policies" OFF)
option(MI_SECURE "Use full security mitigations (like guard pages, allocation randomization, double-free mitigation, and free-list corruption detection)" OFF)
option(MI_PADDING "Enable padding to detect heap block overflow (always on in DEBUG or SECURE mode, or with Valgrind/ASAN)" OFF)
option(MI_OVERRIDE "Override the standard malloc interface (i.e. define entry points for 'malloc', 'free', etc)" ON)
Expand Down
1 change: 0 additions & 1 deletion src/alloc-override.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ typedef void* mi_nothrow_t;
#if (defined(__GNUC__) || defined(__clang__)) && !defined(__APPLE__) && !MI_TRACK_ENABLED
// gcc, clang: use aliasing to alias the exported function to one of our `mi_` functions
#if (defined(__GNUC__) && __GNUC__ >= 9)
#pragma GCC diagnostic ignored "-Wattributes" // or we get warnings that nodiscard is ignored on a forward
#define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun)));
#else
#define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default")));
Expand Down
13 changes: 13 additions & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ terms of the MIT license. A copy of the license can be found in the file
#define _DEFAULT_SOURCE // for realpath() on Linux
#endif

#ifndef MI_CRAN_COMPLIANT
#define MI_CRAN_COMPLIANT 0
#else
#if MI_CRAN_COMPLIANT
#include <R.h>
#endif
#endif

#include "mimalloc.h"
#include "mimalloc/internal.h"
#include "mimalloc/atomic.h"
Expand Down Expand Up @@ -536,10 +544,15 @@ static std_new_handler_t mi_get_new_handler(void) {
static bool mi_try_new_handler(bool nothrow) {
std_new_handler_t h = mi_get_new_handler();
if (h==NULL) {
#if MI_CRAN_COMPLIANT
if (!nothrow)
Rf_error("out of memory in 'new'"); // R's error mechanism
#else
_mi_error_message(ENOMEM, "out of memory in 'new'");
if (!nothrow) {
abort(); // cannot throw in plain C, use abort
}
#endif
return false;
}
else {
Expand Down
41 changes: 38 additions & 3 deletions src/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ terms of the MIT license. A copy of the license can be found in the file
#include <stdio.h> // stdin/stdout
#include <stdlib.h> // abort


#ifndef MI_CRAN_COMPLIANT
#define MI_CRAN_COMPLIANT 0
#else
#if MI_CRAN_COMPLIANT
#include <R.h>
#endif
#endif

static long mi_max_error_count = 16; // stop outputting errors after this (use < 0 for no limit)
static long mi_max_warning_count = 16; // stop outputting warnings after this (use < 0 for no limit)
Expand Down Expand Up @@ -207,7 +213,13 @@ void mi_options_print(void) mi_attr_noexcept
const int vermajor = MI_MALLOC_VERSION/100;
const int verminor = (MI_MALLOC_VERSION%100)/10;
const int verpatch = (MI_MALLOC_VERSION%10);
_mi_message("v%i.%i.%i%s%s (built on %s, %s)\n", vermajor, verminor, verpatch,
_mi_message(
#if MI_CRAN_COMPLIANT
"v%i.%i.%i%s%s\n"
#else
"v%i.%i.%i%s%s (built on %s, %s)\n",
#endif
, vermajor, verminor, verpatch,
#if defined(MI_CMAKE_BUILD_TYPE)
", " mi_stringify(MI_CMAKE_BUILD_TYPE)
#else
Expand All @@ -219,7 +231,10 @@ void mi_options_print(void) mi_attr_noexcept
#else
""
#endif
, __DATE__, __TIME__);
#if !MI_CRAN_COMPLIANT
, __DATE__, __TIME__
#endif
);

// show options
for (int i = 0; i < _mi_option_last; i++) {
Expand Down Expand Up @@ -446,7 +461,11 @@ static void mi_recurse_exit(void) {
}

void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) {
#if MI_CRAN_COMPLIANT
if (out==NULL) {
#else
if (out==NULL || (void*)out==(void*)stdout || (void*)out==(void*)stderr) { // TODO: use mi_out_stderr for stderr?
#endif
if (!mi_recurse_enter()) return;
out = mi_out_get_default(&arg);
if (prefix != NULL) out(prefix, arg);
Expand Down Expand Up @@ -534,7 +553,11 @@ void _mi_warning_message(const char* fmt, ...) {
#if MI_DEBUG
mi_decl_noreturn mi_decl_cold void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) mi_attr_noexcept {
_mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion);
#if MI_CRAN_COMPLIANT
Rf_error("mimalloc: assertion failed");
#else
abort();
#endif
}
#endif

Expand All @@ -552,17 +575,29 @@ static void mi_error_default(int err) {
#ifdef _MSC_VER
__debugbreak();
#endif
#if MI_CRAN_COMPLIANT
Rf_error("mimalloc: error: EFAULT");
#else
abort();
#endif
}
#endif
#if (MI_SECURE>0)
if (err==EFAULT) { // abort on serious errors in secure mode (corrupted meta-data)
#if MI_CRAN_COMPLIANT
Rf_error("mimalloc: error: EFAULT");
#else
abort();
#endif
}
#endif
#if defined(MI_XMALLOC)
if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode
#if MI_CRAN_COMPLIANT
Rf_error("mimalloc: error: out of memory");
#else
abort();
#endif
}
#endif
}
Expand Down
13 changes: 0 additions & 13 deletions src/prim/osx/alloc-override-zone.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,6 @@ static boolean_t intro_zone_locked(malloc_zone_t* zone) {
return false;
}


/* ------------------------------------------------------
At process start, override the default allocator
------------------------------------------------------ */

#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif

#if defined(__clang__)
#pragma clang diagnostic ignored "-Wc99-extensions"
#endif

static malloc_introspection_t mi_introspect = {
.enumerator = &intro_enumerator,
.good_size = &intro_good_size,
Expand Down
8 changes: 8 additions & 0 deletions src/prim/unix/prim.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ terms of the MIT license. A copy of the license can be found in the file
#define _DEFAULT_SOURCE // ensure mmap flags and syscall are defined
#endif

#ifndef MI_CRAN_COMPLIANT
#define MI_CRAN_COMPLIANT 0
#endif

#if defined(__sun)
// illumos provides new mman.h api when any of these are defined
// otherwise the old api based on caddr_t which predates the void pointers one.
Expand Down Expand Up @@ -774,7 +778,11 @@ void _mi_prim_process_info(mi_process_info_t* pinfo)
//----------------------------------------------------------------

void _mi_prim_out_stderr( const char* msg ) {
#if MI_CRAN_COMPLIANT
return;
#else
fputs(msg,stderr);
#endif
}


Expand Down
8 changes: 8 additions & 0 deletions src/prim/wasi/prim.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ terms of the MIT license. A copy of the license can be found in the file
#include <stdio.h> // fputs
#include <stdlib.h> // getenv

#ifndef MI_CRAN_COMPLIANT
#define MI_CRAN_COMPLIANT 0
#endif

//---------------------------------------------
// Initialize
//---------------------------------------------
Expand Down Expand Up @@ -230,7 +234,11 @@ void _mi_prim_process_info(mi_process_info_t* pinfo)
//----------------------------------------------------------------

void _mi_prim_out_stderr( const char* msg ) {
#if MI_CRAN_COMPLIANT
return;
#else
fputs(msg,stderr);
#endif
}


Expand Down
10 changes: 9 additions & 1 deletion src/prim/windows/prim.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ terms of the MIT license. A copy of the license can be found in the file
#include "mimalloc/prim.h"
#include <stdio.h> // fputs, stderr

#ifndef MI_CRAN_COMPLIANT
#define MI_CRAN_COMPLIANT 0
#endif

// xbox has no console IO
#if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
#define MI_HAS_CONSOLE_IO
Expand Down Expand Up @@ -588,8 +592,12 @@ void _mi_prim_out_stderr( const char* msg )
WriteFile(hcon, msg, (DWORD)len, &written, NULL);
}
else {
// finally fall back to fputs after all
#if MI_CRAN_COMPLIANT
return;
#else
// finally fall back to fputs after all
fputs(msg, stderr);
#endif
}
}
}
Expand Down