Skip to content

Commit

Permalink
Integrate mimalloc allocator
Browse files Browse the repository at this point in the history
  • Loading branch information
RandomShaper committed Nov 27, 2024
1 parent 9e60984 commit 29e9a4f
Show file tree
Hide file tree
Showing 53 changed files with 17,535 additions and 5 deletions.
3 changes: 3 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,9 @@ SConscript("main/SCsub")

SConscript("platform/" + env["platform"] + "/SCsub") # Build selected platform.

if "mimalloc" in env.get("supported", []):
SConscript("mimalloc/SCsub")

# Microsoft Visual Studio Project Generation
if env["vsproj"]:
methods.generate_cpp_hint_file("cpp.hint")
Expand Down
102 changes: 102 additions & 0 deletions mimalloc/SCsub
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *

Import("env")

# For platforms not supported out-of-the-box by mimalloc, the following options
# can be used to add support for them:
# mimalloc_custom_prims (bool): If true, the prim.c file is not included. Important because otherwise it falls back to UNIX.
# mimalloc_custom_tls_slot (bool): If true, mimalloc is built assuming primitives for TLS operations will be provided separately.
# mimalloc_custom_get_thread_id (string): If non-empty, mimalloc will use the function named here to get the current thread id.


mimalloc_sources = []

if env["platform"] == "windows":
override_type = "windows"
elif env.get("mimalloc_custom_prims"):
override_type = "none"
else:
override_type = "static"

use_mingw_custom_tls_slot = override_type == "windows" and not env.msvc

# Thirdparty source files

env_thirdparty = env.Clone()
env_thirdparty.disable_warnings()

thirdparty_obj = []

thirdparty_dir = "#thirdparty/mimalloc/"
if override_type == "static":
thirdparty_sources = ["src/static.c"]
env_thirdparty.Append(CPPDEFINES=["MI_MALLOC_OVERRIDE"])
else:
thirdparty_sources = [
"src/alloc.c",
"src/alloc-aligned.c",
"src/alloc-posix.c",
"src/arena.c",
"src/bitmap.c",
"src/heap.c",
"src/init.c",
"src/libc.c",
"src/options.c",
"src/os.c",
"src/page.c",
"src/random.c",
"src/segment-map.c",
"src/segment.c",
"src/stats.c",
]
if not env.get("mimalloc_custom_prims"):
thirdparty_sources += ["src/prim/prim.c"]
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]

if use_mingw_custom_tls_slot:
thirdparty_sources += ["#mimalloc/mingw_custom_tls_slot.cpp"]

env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)

env_thirdparty.Append(CPPDEFINES=[("MI_TRACK_ASAN", 1 if env.get("use_asan") else 0)])

if env.get("mimalloc_custom_tls_slot") or use_mingw_custom_tls_slot:
env_thirdparty.Append(CPPFLAGS=["-includemimalloc/custom_tls_slot.h"])

if env.get("mimalloc_custom_get_thread_id"):
env_thirdparty.Append(CPPDEFINES=[("MI_PRIM_THREAD_ID", env.get("mimalloc_custom_get_thread_id"))])

env_thirdparty.Append(CPPPATH=[f"{thirdparty_dir}include/"])

mimalloc_sources += thirdparty_obj


# Godot source files

godot_obj = []

env_mimalloc = env_thirdparty.Clone()
env_mimalloc.Append(CPPPATH=[thirdparty_dir])

if override_type == "windows":
env_mimalloc.add_source_files(godot_obj, "windows_override.cpp")

mimalloc_sources += godot_obj


if override_type == "windows":
if env.msvc:
if env["arch"] == "x86_32":
env.Append(LINKFLAGS=["/INCLUDE:_mimalloc_godot_force_override"])
else:
env.Append(LINKFLAGS=["/INCLUDE:mimalloc_godot_force_override"])


lib = env.add_library("mimalloc", mimalloc_sources)

# For override to work on non-Windows platforms, it must be linked first.
# This way is somewhat hacky, but reliable.
env.Prepend(LINKFLAGS=[f"mimalloc/{lib[0].get_path()}"])
# We still add it the regular way to ensure the program depends on it.
env.Prepend(LIBS=[lib])
55 changes: 55 additions & 0 deletions mimalloc/custom_tls_slot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**************************************************************************/
/* custom_tls_slot.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/**************************************************************************/

#ifndef CUSTOM_TLS_SLOT_H
#define CUSTOM_TLS_SLOT_H

#include <stddef.h>

// This is included both in the third-party and the engine code
// to ensure both mimalloc and Godot see the same, non-default,
// signatures. Otherwise, for instance, in mimalloc mi_prim_tls_slot()
// could be assumed to return 'int', which would truncate pointers.

#define MI_HAS_TLS_SLOT
#define MI_TLS_SLOT 0

#ifdef __cplusplus
extern "C" {
#endif

void *mi_prim_tls_slot(size_t slot);
void mi_prim_tls_slot_set(size_t slot, void *value);

#ifdef __cplusplus
}
#endif

#endif // CUSTOM_TLS_SLOT_H
58 changes: 58 additions & 0 deletions mimalloc/mingw_custom_tls_slot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**************************************************************************/
/* mingw_custom_tls_slot.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/**************************************************************************/

#include "core/error/error_macros.h"
#include "core/typedefs.h"
#include "mimalloc/custom_tls_slot.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

static DWORD tls_slot = -1;

extern "C" {
void *mi_prim_tls_slot(size_t slot) {
DEV_ASSERT(slot == MI_TLS_SLOT);
if (unlikely(tls_slot == -1)) {
return nullptr;
} else {
return TlsGetValue(tls_slot);
}
}

void mi_prim_tls_slot_set(size_t slot, void *value) {
DEV_ASSERT(slot == MI_TLS_SLOT);
if (unlikely(tls_slot == -1)) {
tls_slot = TlsAlloc();
CRASH_COND(tls_slot == TLS_OUT_OF_INDEXES);
}
TlsSetValue(tls_slot, value);
}
}
Loading

0 comments on commit 29e9a4f

Please sign in to comment.