update override on macOS with interpose of malloc_default_zone (issues #313)
This commit is contained in:
parent
745cf1e2f5
commit
bb386025b5
@ -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
|
||||
#endif
|
||||
|
||||
|
||||
// "options.c"
|
||||
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, ...);
|
||||
|
@ -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));
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------
|
||||
malloc zone members
|
||||
------------------------------------------------------ */
|
||||
@ -44,7 +43,7 @@ static size_t zone_size(malloc_zone_t* zone, const void* p) {
|
||||
UNUSED(zone);
|
||||
if (!mi_is_in_heap_region(p))
|
||||
return 0; // not our pointer, bail out
|
||||
|
||||
|
||||
return mi_usable_size(p);
|
||||
}
|
||||
|
||||
@ -190,63 +189,85 @@ static malloc_zone_t* mi_get_default_zone()
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) _mi_macos_override_malloc()
|
||||
{
|
||||
static malloc_introspection_t intro;
|
||||
memset(&intro, 0, sizeof(intro));
|
||||
static malloc_introspection_t mi_introspect = {
|
||||
.enumerator = &intro_enumerator,
|
||||
.good_size = &intro_good_size,
|
||||
.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;
|
||||
intro.good_size = &intro_good_size;
|
||||
intro.check = &intro_check;
|
||||
intro.print = &intro_print;
|
||||
intro.log = &intro_log;
|
||||
intro.force_lock = &intro_force_lock;
|
||||
intro.force_unlock = &intro_force_unlock;
|
||||
static malloc_zone_t mi_malloc_zone = {
|
||||
.size = &zone_size,
|
||||
.zone_name = "mimalloc",
|
||||
.introspect = &mi_introspect,
|
||||
.malloc = &zone_malloc,
|
||||
.calloc = &zone_calloc,
|
||||
.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;
|
||||
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;
|
||||
#if defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE)
|
||||
|
||||
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;
|
||||
|
||||
#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.
|
||||
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
|
||||
if (malloc_default_purgeable_zone) {
|
||||
purgeable_zone = malloc_default_purgeable_zone();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Register our zone
|
||||
malloc_zone_register(&zone);
|
||||
|
||||
// Register our 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
|
||||
// as that was the last registered.
|
||||
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.
|
||||
malloc_zone_register(default_zone);
|
||||
// Reregister the default zone so free and realloc in that zone keep working.
|
||||
malloc_zone_register(default_zone);
|
||||
}
|
||||
|
||||
// Unregister, and re-register the purgeable_zone to avoid bugs if it occurs
|
||||
// earlier than the default zone.
|
||||
@ -257,4 +278,4 @@ static void __attribute__((constructor)) _mi_macos_override_malloc()
|
||||
|
||||
}
|
||||
|
||||
#endif // MI_MALLOC_OVERRIDE
|
||||
#endif // MI_MALLOC_OVERRIDE
|
@ -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(reallocf),
|
||||
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>)
|
||||
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 bool mi_recurse_enter(void) {
|
||||
#ifdef MI_TLS_RECURSE_GUARD
|
||||
#if defined(__MACH__) || defined(MI_TLS_RECURSE_GUARD)
|
||||
if (_mi_preloading()) return true;
|
||||
#endif
|
||||
if (recurse) return false;
|
||||
@ -268,7 +268,7 @@ static bool mi_recurse_enter(void) {
|
||||
}
|
||||
|
||||
static void mi_recurse_exit(void) {
|
||||
#ifdef MI_TLS_RECURSE_GUARD
|
||||
#if defined(__MACH__) || defined(MI_TLS_RECURSE_GUARD)
|
||||
if (_mi_preloading()) return;
|
||||
#endif
|
||||
recurse = false;
|
||||
|
@ -20,7 +20,6 @@ terms of the MIT license.
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <mimalloc.h>
|
||||
|
||||
// > 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_free(p) free(p)
|
||||
#else
|
||||
#include <mimalloc.h>
|
||||
#define custom_calloc(n,s) mi_calloc(n,s)
|
||||
#define custom_realloc(p,s) mi_realloc(p,s)
|
||||
#define custom_free(p) mi_free(p)
|
||||
@ -251,7 +251,9 @@ int main(int argc, char** argv) {
|
||||
#endif
|
||||
|
||||
// mi_collect(true);
|
||||
#ifndef USE_STD_MALLOC
|
||||
mi_stats_print(NULL);
|
||||
#endif
|
||||
//bench_end_program();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user