Skip to content

Commit

Permalink
Mimalloc is vendored instead of fetched (#1320)
Browse files Browse the repository at this point in the history
These changes copy a snapshot of the Mimalloc source from `v2.1.2` into
the mimalloc-sys folder so that we no longer need to use cmake to fetch
and prepare the source. This also fixes `aarch64` Windows
cross-compilation issues caused by cmake generators.

I have addressed all DevSkim feedback and nothing was applicable or
actionable.

I've run the release build and everything compiles. It shows a red X in
the checks as I cancelled the second half of the build to prevent the
release from going out.

Closes #1281
  • Loading branch information
idavis committed Mar 28, 2024
1 parent 3b8abfd commit 91589c3
Show file tree
Hide file tree
Showing 49 changed files with 16,213 additions and 112 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ __pycache__/
.vscode/
.vscode-test-web/
.venv/
/allocator/
/compiler/
/jupyterlab/lib/
/jupyterlab/qsharp-jupyterlab/labextension/
Expand Down
10 changes: 0 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ To build this repository there are dependencies that need to be installed. These
- Rust (<https://www.rust-lang.org/tools/install>)
- Node.js (<https://nodejs.org/>)
- wasm-pack (<https://rustwasm.github.io/wasm-pack/installer/>)
- cmake (<https://cmake.org/>) and a C compiler
- A [C compiler](https://docs.rs/cc/latest/cc/#compile-time-requirements)

The build script will check these dependencies and their versions and fail if not met. (Or run
`python ./prereqs.py` directly to check if the minimum required versions are installed).
Expand Down
2 changes: 1 addition & 1 deletion allocator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition.workspace = true
license.workspace = true
version.workspace = true

[target.'cfg(not(any(target_family = "wasm", all(target_family = "windows", target_arch = "aarch64"))))'.dependencies]
[target.'cfg(not(any(target_family = "wasm")))'.dependencies]
mimalloc-sys = { path = "./mimalloc-sys" }

[lints]
Expand Down
20 changes: 0 additions & 20 deletions allocator/mimalloc-sys/CMakeLists.txt

This file was deleted.

2 changes: 0 additions & 2 deletions allocator/mimalloc-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,4 @@ version.workspace = true
workspace = true

[build-dependencies]
cmake = "0.1"
cc = "1.0"

65 changes: 20 additions & 45 deletions allocator/mimalloc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,41 @@ use std::boxed::Box;
use std::env;
use std::error::Error;
use std::fs;
use std::path::{Path, PathBuf};

use cmake::Config;

// 1.8.2
//static ALLOCATOR_MIMALLOC_TAG: &str = "b66e3214d8a104669c2ec05ae91ebc26a8f5ab78";
// 2.1.2
static ALLOCATOR_MIMALLOC_TAG: &str = "43ce4bd7fd34bcc730c1c7471c99995597415488";
use std::path::PathBuf;

fn main() -> Result<(), Box<dyn Error>> {
let dst = download_mimalloc()?;
compile_mimalloc(&dst);
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=CMakeLists.txt");
compile_mimalloc();
let build_dir = get_build_dir()?;
println!(
"cargo:rerun-if-changed={}",
build_dir.join("mimalloc").display()
);
Ok(())
}

// Compile mimalloc source code and link it to the crate.
// The cc crate is used to compile the source code into a static library.
// The cmake crate is used to download the source code and stage it in the build directory.
// We don't use the cmake crate to compile the source code because the mimalloc build system
// loads extra libraries, changes the name and path around, and does other things that are
// difficult to handle. The cc crate is much simpler and more predictable.
fn compile_mimalloc(dst: &Path) {
let src_dir = dst
.join("build")
.join("mimalloc-prefix")
.join("src")
.join("mimalloc");
fn compile_mimalloc() {
let mimalloc_vendor_dir = PathBuf::from("mimalloc");

let mut build = cc::Build::new();

build.include(src_dir.join("include"));
build.include(src_dir.join("src"));
build.file(src_dir.join("src/static.c"));
let include_dir = mimalloc_vendor_dir.join("include");
let src_dir = mimalloc_vendor_dir.join("src");
let static_file = src_dir.join("static.c");

assert!(include_dir.exists(), "include_dir: {include_dir:?}");
assert!(src_dir.exists(), "src_dir: {src_dir:?}");
assert!(static_file.exists(), "static_file: {static_file:?}");

build.include(include_dir);
build.include(src_dir);
build.file(static_file);

if build.get_compiler().is_like_msvc() {
build.cpp(true);
build.static_crt(true);
}
// turn off debug mode
Expand All @@ -52,28 +49,6 @@ fn compile_mimalloc(dst: &Path) {
//build.opt_level(3);

build.compile("mimalloc");

println!(
"cargo:rustc-link-search=native={}",
dst.join("lib").display()
);
println!("cargo:rustc-link-lib=static=mimalloc");
}

// Use cmake to download mimalloc source code and stage
// it in the build directory.
fn download_mimalloc() -> Result<PathBuf, Box<dyn Error>> {
let build_dir = get_build_dir()?;
let mut config = Config::new(build_dir);

config
.no_build_target(true)
.env("ALLOCATOR_MIMALLOC_TAG", ALLOCATOR_MIMALLOC_TAG)
.very_verbose(true);

let dst = config.build();

Ok(dst)
}

fn get_build_dir() -> Result<PathBuf, Box<dyn Error>> {
Expand Down
21 changes: 21 additions & 0 deletions allocator/mimalloc-sys/mimalloc/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.
3 changes: 3 additions & 0 deletions allocator/mimalloc-sys/mimalloc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Mimalloc

The `src`/`include` folders contain the [mimalloc](https://github.com/microsoft/mimalloc) source from [`v2.1.2`](https://github.com/microsoft/mimalloc/tree/v2.1.2)(`43ce4bd7fd34bcc730c1c7471c99995597415488`).
66 changes: 66 additions & 0 deletions allocator/mimalloc-sys/mimalloc/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
67 changes: 67 additions & 0 deletions allocator/mimalloc-sys/mimalloc/include/mimalloc-override.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* ----------------------------------------------------------------------------
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 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

0 comments on commit 91589c3

Please sign in to comment.