mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-05 06:59:32 +03:00
update override on macOS with interpose of malloc_default_zone (issues #313)
This commit is contained in:
parent
745cf1e2f5
commit
bb386025b5
5 changed files with 75 additions and 46 deletions
|
@ -32,7 +32,6 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#define mi_decl_cache_align
|
#define mi_decl_cache_align
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// "options.c"
|
// "options.c"
|
||||||
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
|
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
|
||||||
void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);
|
void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);
|
||||||
|
|
|
@ -35,7 +35,6 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import));
|
extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------
|
/* ------------------------------------------------------
|
||||||
malloc zone members
|
malloc zone members
|
||||||
------------------------------------------------------ */
|
------------------------------------------------------ */
|
||||||
|
@ -190,63 +189,85 @@ static malloc_zone_t* mi_get_default_zone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __attribute__((constructor)) _mi_macos_override_malloc()
|
static malloc_introspection_t mi_introspect = {
|
||||||
{
|
.enumerator = &intro_enumerator,
|
||||||
static malloc_introspection_t intro;
|
.good_size = &intro_good_size,
|
||||||
memset(&intro, 0, sizeof(intro));
|
.check = &intro_check,
|
||||||
|
.print = &intro_print,
|
||||||
|
.log = &intro_log,
|
||||||
|
.force_lock = &intro_force_lock,
|
||||||
|
.force_unlock = &intro_force_unlock,
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_6) && \
|
||||||
|
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||||
|
.zone_locked = &intro_zone_locked,
|
||||||
|
.statistics = &intro_statistics,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
intro.enumerator = &intro_enumerator;
|
static malloc_zone_t mi_malloc_zone = {
|
||||||
intro.good_size = &intro_good_size;
|
.size = &zone_size,
|
||||||
intro.check = &intro_check;
|
.zone_name = "mimalloc",
|
||||||
intro.print = &intro_print;
|
.introspect = &mi_introspect,
|
||||||
intro.log = &intro_log;
|
.malloc = &zone_malloc,
|
||||||
intro.force_lock = &intro_force_lock;
|
.calloc = &zone_calloc,
|
||||||
intro.force_unlock = &intro_force_unlock;
|
.valloc = &zone_valloc,
|
||||||
|
.free = &zone_free,
|
||||||
|
.realloc = &zone_realloc,
|
||||||
|
.destroy = &zone_destroy,
|
||||||
|
.batch_malloc = &zone_batch_malloc,
|
||||||
|
.batch_free = &zone_batch_free,
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_6) && \
|
||||||
|
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||||
|
// switch to version 9 on OSX 10.6 to support memalign.
|
||||||
|
.version = 9,
|
||||||
|
.memalign = &zone_memalign,
|
||||||
|
.free_definite_size = &zone_free_definite_size,
|
||||||
|
.pressure_relief = &zone_pressure_relief,
|
||||||
|
#else
|
||||||
|
.version = 4,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static malloc_zone_t zone;
|
|
||||||
memset(&zone, 0, sizeof(zone));
|
|
||||||
|
|
||||||
zone.version = 4;
|
#if defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE)
|
||||||
zone.zone_name = "mimalloc";
|
|
||||||
zone.size = &zone_size;
|
|
||||||
zone.introspect = &intro;
|
|
||||||
zone.malloc = &zone_malloc;
|
|
||||||
zone.calloc = &zone_calloc;
|
|
||||||
zone.valloc = &zone_valloc;
|
|
||||||
zone.free = &zone_free;
|
|
||||||
zone.realloc = &zone_realloc;
|
|
||||||
zone.destroy = &zone_destroy;
|
|
||||||
zone.batch_malloc = &zone_batch_malloc;
|
|
||||||
zone.batch_free = &zone_batch_free;
|
|
||||||
|
|
||||||
|
static malloc_zone_t *mi_malloc_default_zone(void) {
|
||||||
|
return &mi_malloc_zone;
|
||||||
|
}
|
||||||
|
// TODO: should use the macros in alloc-override but they aren't available here.
|
||||||
|
__attribute__((used)) static struct {
|
||||||
|
const void *replacement;
|
||||||
|
const void *target;
|
||||||
|
} replace_malloc_default_zone[] __attribute__((section("__DATA, __interpose"))) = {
|
||||||
|
{ (const void*)mi_malloc_default_zone, (const void*)malloc_default_zone },
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void __attribute__((constructor(0))) _mi_macos_override_malloc() {
|
||||||
malloc_zone_t* purgeable_zone = NULL;
|
malloc_zone_t* purgeable_zone = NULL;
|
||||||
|
|
||||||
#if defined(MAC_OS_X_VERSION_10_6) && \
|
#if defined(MAC_OS_X_VERSION_10_6) && \
|
||||||
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||||
// switch to version 9 on OSX 10.6 to support memalign.
|
|
||||||
zone.version = 9;
|
|
||||||
zone.memalign = &zone_memalign;
|
|
||||||
zone.free_definite_size = &zone_free_definite_size;
|
|
||||||
zone.pressure_relief = &zone_pressure_relief;
|
|
||||||
intro.zone_locked = &intro_zone_locked;
|
|
||||||
intro.statistics = &intro_statistics;
|
|
||||||
|
|
||||||
// force the purgeable zone to exist to avoid strange bugs
|
// force the purgeable zone to exist to avoid strange bugs
|
||||||
if (malloc_default_purgeable_zone) {
|
if (malloc_default_purgeable_zone) {
|
||||||
purgeable_zone = malloc_default_purgeable_zone();
|
purgeable_zone = malloc_default_purgeable_zone();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Register our zone
|
// Register our zone.
|
||||||
malloc_zone_register(&zone);
|
// thomcc: I think this is still needed to put us in the zone list.
|
||||||
|
malloc_zone_register(&mi_malloc_zone);
|
||||||
// Unregister the default zone, this makes our zone the new default
|
// Unregister the default zone, this makes our zone the new default
|
||||||
// as that was the last registered.
|
// as that was the last registered.
|
||||||
malloc_zone_t *default_zone = mi_get_default_zone();
|
malloc_zone_t *default_zone = mi_get_default_zone();
|
||||||
malloc_zone_unregister(default_zone);
|
// thomcc: Unsure if the next test is *always* false or just false in the
|
||||||
|
// cases I've tried. I'm also unsure if the code inside is needed. at all
|
||||||
|
if (default_zone != &mi_malloc_zone) {
|
||||||
|
malloc_zone_unregister(default_zone);
|
||||||
|
|
||||||
// Reregister the default zone so free and realloc in that zone keep working.
|
// Reregister the default zone so free and realloc in that zone keep working.
|
||||||
malloc_zone_register(default_zone);
|
malloc_zone_register(default_zone);
|
||||||
|
}
|
||||||
|
|
||||||
// Unregister, and re-register the purgeable_zone to avoid bugs if it occurs
|
// Unregister, and re-register the purgeable_zone to avoid bugs if it occurs
|
||||||
// earlier than the default zone.
|
// earlier than the default zone.
|
||||||
|
|
|
@ -60,6 +60,13 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
MI_INTERPOSE_MI(posix_memalign),
|
MI_INTERPOSE_MI(posix_memalign),
|
||||||
MI_INTERPOSE_MI(reallocf),
|
MI_INTERPOSE_MI(reallocf),
|
||||||
MI_INTERPOSE_MI(valloc),
|
MI_INTERPOSE_MI(valloc),
|
||||||
|
#ifndef MI_OSX_ZONE
|
||||||
|
// some code allocates from default zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)
|
||||||
|
MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us
|
||||||
|
#else
|
||||||
|
// We interpose malloc_default_zone in alloc-override-osx.c
|
||||||
|
MI_INTERPOSE_MI(free),
|
||||||
|
#endif
|
||||||
// some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)
|
// some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity <https://github.com/nneonneo/osx-10.9-opensource/blob/master/objc4-551.1/runtime/hashtable2.mm>)
|
||||||
MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us
|
MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us
|
||||||
};
|
};
|
||||||
|
|
|
@ -259,7 +259,7 @@ static _Atomic(uintptr_t) warning_count; // = 0; // when >= max_warning_count s
|
||||||
static mi_decl_thread bool recurse = false;
|
static mi_decl_thread bool recurse = false;
|
||||||
|
|
||||||
static bool mi_recurse_enter(void) {
|
static bool mi_recurse_enter(void) {
|
||||||
#ifdef MI_TLS_RECURSE_GUARD
|
#if defined(__MACH__) || defined(MI_TLS_RECURSE_GUARD)
|
||||||
if (_mi_preloading()) return true;
|
if (_mi_preloading()) return true;
|
||||||
#endif
|
#endif
|
||||||
if (recurse) return false;
|
if (recurse) return false;
|
||||||
|
@ -268,7 +268,7 @@ static bool mi_recurse_enter(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_recurse_exit(void) {
|
static void mi_recurse_exit(void) {
|
||||||
#ifdef MI_TLS_RECURSE_GUARD
|
#if defined(__MACH__) || defined(MI_TLS_RECURSE_GUARD)
|
||||||
if (_mi_preloading()) return;
|
if (_mi_preloading()) return;
|
||||||
#endif
|
#endif
|
||||||
recurse = false;
|
recurse = false;
|
||||||
|
|
|
@ -20,7 +20,6 @@ terms of the MIT license.
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mimalloc.h>
|
|
||||||
|
|
||||||
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
||||||
//
|
//
|
||||||
|
@ -43,6 +42,7 @@ static size_t use_one_size = 0; // use single object size of `N * s
|
||||||
#define custom_realloc(p,s) realloc(p,s)
|
#define custom_realloc(p,s) realloc(p,s)
|
||||||
#define custom_free(p) free(p)
|
#define custom_free(p) free(p)
|
||||||
#else
|
#else
|
||||||
|
#include <mimalloc.h>
|
||||||
#define custom_calloc(n,s) mi_calloc(n,s)
|
#define custom_calloc(n,s) mi_calloc(n,s)
|
||||||
#define custom_realloc(p,s) mi_realloc(p,s)
|
#define custom_realloc(p,s) mi_realloc(p,s)
|
||||||
#define custom_free(p) mi_free(p)
|
#define custom_free(p) mi_free(p)
|
||||||
|
@ -251,7 +251,9 @@ int main(int argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// mi_collect(true);
|
// mi_collect(true);
|
||||||
|
#ifndef USE_STD_MALLOC
|
||||||
mi_stats_print(NULL);
|
mi_stats_print(NULL);
|
||||||
|
#endif
|
||||||
//bench_end_program();
|
//bench_end_program();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue