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
175 changes: 175 additions & 0 deletions vendor/mimalloc/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
const std = @import("std");

pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const MI_SECURE = b.option(bool, "MI_SECURE", "Use full security mitigations (like guard pages, allocation randomization, double-free mitigation, and free-list corruption detection)") orelse false;
const MI_DEBUG_FULL = b.option(bool, "MI_DEBUG_FULL", "Use full internal heap invariant checking in DEBUG mode (expensive)") orelse false;
const MI_PADDING = b.option(bool, "MI_PADDING", "Enable padding to detect heap block overflow (always on in DEBUG or SECURE mode, or with Valgrind/ASAN)") orelse false;
const MI_OVERRIDE = b.option(bool, "MI_OVERRIDE", "Override the standard malloc interface (e.g. define entry points for malloc() etc)") orelse true;
const MI_XMALLOC = b.option(bool, "MI_XMALLOC", "Enable abort() call on memory allocation failure by default") orelse false;
const MI_SHOW_ERRORS = b.option(bool, "MI_SHOW_ERRORS", "Show error and warning messages by default (only enabled by default in DEBUG mode)") orelse false;
const MI_TRACK_VALGRIND = b.option(bool, "MI_TRACK_VALGRIND", "Compile with Valgrind support (adds a small overhead)") orelse false;
const MI_TRACK_ASAN = b.option(bool, "MI_TRACK_ASAN", "Compile with address sanitizer support (adds a small overhead)") orelse false;
const MI_TRACK_ETW = b.option(bool, "MI_TRACK_ETW", "Compile with Windows event tracing (ETW) support (adds a small overhead)") orelse false;
// const MI_USE_CXX = b.option(bool, "MI_USE_CXX", "Use the C++ compiler to compile the library (instead of the C compiler)") orelse false;
// const MI_SEE_ASM = b.option(bool, "MI_SEE_ASM", "Generate assembly files") orelse false;
const MI_OSX_INTERPOSE = b.option(bool, "MI_OSX_INTERPOSE", "Use interpose to override standard malloc on macOS") orelse true;
const MI_OSX_ZONE = b.option(bool, "MI_OSX_ZONE", "Use malloc zone to override standard malloc on macOS") orelse true;
const MI_WIN_REDIRECT = b.option(bool, "MI_WIN_REDIRECT", "Use redirection module ('mimalloc-redirect') on Windows if compiling mimalloc as a DLL") orelse true;
const MI_LOCAL_DYNAMIC_TLS = b.option(bool, "MI_LOCAL_DYNAMIC_TLS", "Use slightly slower, dlopen-compatible TLS mechanism (Unix)") orelse false;
// const MI_LIBC_MUSL = b.option(bool, "MI_LIBC_MUSL", "Set this when linking with musl libc") orelse false;
// const MI_BUILD_SHARED = b.option(bool, "MI_BUILD_SHARED", "Build shared library") orelse true;
// const MI_BUILD_STATIC = b.option(bool, "MI_BUILD_STATIC", "Build static library") orelse true;
// const MI_BUILD_OBJECT = b.option(bool, "MI_BUILD_OBJECT", "Build object library") orelse true;
// const MI_BUILD_TESTS = b.option(bool, "MI_BUILD_TESTS", "Build test executables") orelse true;
const MI_DEBUG_TSAN = b.option(bool, "MI_DEBUG_TSAN", "Build with thread sanitizer (needs clang)") orelse false;
// const MI_DEBUG_UBSAN = b.option(bool, "MI_DEBUG_UBSAN", "Build with undefined-behavior sanitizer (needs clang++)") orelse false;
const MI_SKIP_COLLECT_ON_EXIT = b.option(bool, "MI_SKIP_COLLECT_ON_EXIT", "Skip collecting memory on program exit") orelse false;
const MI_NO_PADDING = b.option(bool, "MI_NO_PADDING", "Force no use of padding even in DEBUG mode etc.") orelse false;
// const MI_INSTALL_TOPLEVEL = b.option(bool, "MI_INSTALL_TOPLEVEL", "Install directly into $CMAKE_INSTALL_PREFIX instead of PREFIX/lib/mimalloc-version") orelse false;
const MI_NO_THP = b.option(bool, "MI_NO_THP", "Disable transparent huge pages support on Linux/Android for the mimalloc process only") orelse false;

const mimalloc = b.addModule("mimalloc", .{
.target = target,
.optimize = optimize,
.pic = true,
.link_libc = true,
});

var flags = std.ArrayList([]const u8).init(b.allocator);
defer flags.deinit();

try flags.appendSlice(&.{
"-std=c11",
"-Wall",
"-Wextra",
"-Wpedantic",
});

var sources = try std.ArrayList([]const u8).initCapacity(b.allocator, mimalloc_sources.len);
defer sources.deinit();

sources.appendSlice(&mimalloc_sources) catch unreachable;

if (MI_OVERRIDE) {
if (target.result.isDarwin()) {
if (MI_OSX_ZONE) {
try sources.append("src/prim/osx/alloc-override-zone.c");
mimalloc.addCMacro("MI_OSX_ZONE", "1");
}
if (MI_OSX_INTERPOSE) {
mimalloc.addCMacro("MI_OSX_INTERPOSE", "1");
}
}
}

if (target.result.os.tag == .windows) {
if (target.result.cpu.arch.isARM()) @panic("Cannot use redirection on Windows ARM");
if (!MI_WIN_REDIRECT) {
mimalloc.addCMacro("MI_WIN_NOREDIRECT", "1");
}
}

if (MI_SECURE) mimalloc.addCMacro("MI_SECURE", "4");
if (MI_TRACK_VALGRIND) mimalloc.addCMacro("MI_TRACK_VALGRIND", "1");

if (MI_TRACK_ASAN) {
if (target.result.isDarwin() and MI_OVERRIDE) @panic("Cannot enable address sanitizer support on macOS if MI_OVERRIDE is true");
if (MI_TRACK_VALGRIND) @panic("Cannot enable address sanitizer support with also Valgrind support enabled");
mimalloc.addCMacro("MI_TRACK_ASAN", "1");
try flags.append("-fsanitize=address");
}

if (MI_TRACK_ETW) {
if (target.result.os.tag != .windows) @panic("Can only enable ETW support on Windows");
if (MI_TRACK_VALGRIND or MI_TRACK_ASAN) @panic("Cannot enable ETW support with also Valgrind or ASAN support enabled");
mimalloc.addCMacro("MI_TRACK_ETW", "1");
}

if (MI_SKIP_COLLECT_ON_EXIT) mimalloc.addCMacro("MI_SKIP_COLLECT_ON_EXIT", "1");
if (MI_DEBUG_FULL) mimalloc.addCMacro("MI_DEBUG", "3");
if (MI_NO_PADDING) {
mimalloc.addCMacro("MI_PADDING", "0");
} else if (MI_PADDING) {
mimalloc.addCMacro("MI_PADDING", "1");
}
if (MI_XMALLOC) mimalloc.addCMacro("MI_XMALLOC", "1");
if (MI_SHOW_ERRORS) mimalloc.addCMacro("MI_SHOW_ERRORS", "1");

if (MI_DEBUG_TSAN) {
mimalloc.addCMacro("MI_TSAN", "1");
try flags.appendSlice(&.{ "-fsanitize=thread", "-g", "-O1" });
}

if (target.result.isAndroid() or target.result.os.tag == .linux) {
if (MI_NO_THP) mimalloc.addCMacro("MI_NO_THP", "1");
}

if (target.result.isMusl()) mimalloc.addCMacro("MI_LIBC_MUSL", "1");

try flags.appendSlice(&.{
"-Wno-unknown-pragmas",
"-fvisibility=hidden",
"-Wstrict-prototypes",
"-Wno-static-in-inline",
});

if (target.result.os.tag != .haiku) {
if (MI_LOCAL_DYNAMIC_TLS) {
try flags.append("-ftls-model=local-dynamic");
} else {
if (target.result.isMusl()) {
try flags.append("-ftls-model=local-dynamic");
} else {
try flags.append("-ftls-model=initial-exec");
}
}
if (MI_OVERRIDE) try flags.append("-fno-builtin-malloc");
}

if (target.result.isMinGW()) {
mimalloc.addCMacro("_WIN32_WINNT", "0x600");
}

if (target.result.os.tag == .windows) {
mimalloc.linkSystemLibrary("psapi", .{});
mimalloc.linkSystemLibrary("shell32", .{});
mimalloc.linkSystemLibrary("user32", .{});
mimalloc.linkSystemLibrary("advapi32", .{});
mimalloc.linkSystemLibrary("bcrypt", .{});
} else {
// TODO: Find a way to link them conditionally if they exist
// lib.linkSystemLibrary("pthread");
// lib.linkSystemLibrary("rt");
// lib.linkSystemLibrary("atomic");
}

const upstream = b.dependency("mimalloc", .{});
mimalloc.addCSourceFiles(.{
.root = upstream.path("src"),
.files = sources.items,
.flags = flags.items,
});
mimalloc.addIncludePath(upstream.path("include"));
}

const mimalloc_sources = [_][]const u8{
"alloc.c",
"alloc-aligned.c",
"alloc-posix.c",
"arena.c",
"bitmap.c",
"heap.c",
"init.c",
"libc.c",
"options.c",
"os.c",
"page.c",
"random.c",
"segment.c",
"segment-map.c",
"stats.c",
"prim/prim.c",
};
16 changes: 16 additions & 0 deletions vendor/mimalloc/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.{
.name = "mimalloc",
.version = "2.1.7",

.dependencies = .{
.mimalloc = .{
.path = "mimalloc-2.1.7",
},
},

.paths = .{
"build.zig",
"build.zig.zon",
"mimalloc-2.1.7",
},
}
21 changes: 21 additions & 0 deletions vendor/mimalloc/mimalloc-2.1.7/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2018-2021 Microsoft Corporation, Daan Leijen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
66 changes: 66 additions & 0 deletions vendor/mimalloc/mimalloc-2.1.7/include/mimalloc-new-delete.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* ----------------------------------------------------------------------------
Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
#pragma once
#ifndef MIMALLOC_NEW_DELETE_H
#define MIMALLOC_NEW_DELETE_H

// ----------------------------------------------------------------------------
// This header provides convenient overrides for the new and
// delete operations in C++.
//
// This header should be included in only one source file!
//
// On Windows, or when linking dynamically with mimalloc, these
// can be more performant than the standard new-delete operations.
// See <https://en.cppreference.com/w/cpp/memory/new/operator_new>
// ---------------------------------------------------------------------------
#if defined(__cplusplus)
#include <new>
#include <mimalloc.h>

#if defined(_MSC_VER) && defined(_Ret_notnull_) && defined(_Post_writable_byte_size_)
// stay consistent with VCRT definitions
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict _Ret_notnull_ _Post_writable_byte_size_(n)
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict _Ret_maybenull_ _Success_(return != NULL) _Post_writable_byte_size_(n)
#else
#define mi_decl_new(n) mi_decl_nodiscard mi_decl_restrict
#define mi_decl_new_nothrow(n) mi_decl_nodiscard mi_decl_restrict
#endif

void operator delete(void* p) noexcept { mi_free(p); };
void operator delete[](void* p) noexcept { mi_free(p); };

void operator delete (void* p, const std::nothrow_t&) noexcept { mi_free(p); }
void operator delete[](void* p, const std::nothrow_t&) noexcept { mi_free(p); }

mi_decl_new(n) void* operator new(std::size_t n) noexcept(false) { return mi_new(n); }
mi_decl_new(n) void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); }

mi_decl_new_nothrow(n) void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }
mi_decl_new_nothrow(n) void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); }

#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); };
void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); };
#endif

#if (__cplusplus > 201402L || defined(__cpp_aligned_new))
void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast<size_t>(al)); };
void operator delete (void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }
void operator delete[](void* p, std::align_val_t al, const std::nothrow_t&) noexcept { mi_free_aligned(p, static_cast<size_t>(al)); }

void* operator new (std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast<size_t>(al)); }
void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); }
#endif
#endif

#endif // MIMALLOC_NEW_DELETE_H
68 changes: 68 additions & 0 deletions vendor/mimalloc/mimalloc-2.1.7/include/mimalloc-override.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* ----------------------------------------------------------------------------
Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
This is free software; you can redistribute it and/or modify it under the
terms of the MIT license. A copy of the license can be found in the file
"LICENSE" at the root of this distribution.
-----------------------------------------------------------------------------*/
#pragma once
#ifndef MIMALLOC_OVERRIDE_H
#define MIMALLOC_OVERRIDE_H

/* ----------------------------------------------------------------------------
This header can be used to statically redirect malloc/free and new/delete
to the mimalloc variants. This can be useful if one can include this file on
each source file in a project (but be careful when using external code to
not accidentally mix pointers from different allocators).
-----------------------------------------------------------------------------*/

#include <mimalloc.h>

// Standard C allocation
#define malloc(n) mi_malloc(n)
#define calloc(n,c) mi_calloc(n,c)
#define realloc(p,n) mi_realloc(p,n)
#define free(p) mi_free(p)

#define strdup(s) mi_strdup(s)
#define strndup(s,n) mi_strndup(s,n)
#define realpath(f,n) mi_realpath(f,n)

// Microsoft extensions
#define _expand(p,n) mi_expand(p,n)
#define _msize(p) mi_usable_size(p)
#define _recalloc(p,n,c) mi_recalloc(p,n,c)

#define _strdup(s) mi_strdup(s)
#define _strndup(s,n) mi_strndup(s,n)
#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s))
#define _mbsdup(s) mi_mbsdup(s)
#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v)
#define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v))

// Various Posix and Unix variants
#define reallocf(p,n) mi_reallocf(p,n)
#define malloc_size(p) mi_usable_size(p)
#define malloc_usable_size(p) mi_usable_size(p)
#define malloc_good_size(sz) mi_malloc_good_size(sz)
#define cfree(p) mi_free(p)

#define valloc(n) mi_valloc(n)
#define pvalloc(n) mi_pvalloc(n)
#define reallocarray(p,s,n) mi_reallocarray(p,s,n)
#define reallocarr(p,s,n) mi_reallocarr(p,s,n)
#define memalign(a,n) mi_memalign(a,n)
#define aligned_alloc(a,n) mi_aligned_alloc(a,n)
#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n)
#define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n)

// Microsoft aligned variants
#define _aligned_malloc(n,a) mi_malloc_aligned(n,a)
#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a)
#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a)
#define _aligned_msize(p,a,o) mi_usable_size(p)
#define _aligned_free(p) mi_free(p)
#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o)
#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o)
#define _aligned_offset_recalloc(p,s,n,a,o) mi_recalloc_aligned_at(p,s,n,a,o)

#endif // MIMALLOC_OVERRIDE_H
Loading