Skip to content

Commit 226c1d5

Browse files
committed
eh
1 parent 32bfe9e commit 226c1d5

File tree

6 files changed

+140
-17
lines changed

6 files changed

+140
-17
lines changed

Cargo.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ dirs = { package = "dirs-next", version = "2.0.0" }
4040
env_logger = { version = "0.9.0", default-features = false, features = ["atty", "termcolor"] }
4141
flamescope = { version = "0.1.2", optional = true }
4242

43-
[target.'cfg(all(any(target_os = "linux", target_os = "macos", target_os = "windows"), not(any(target_env = "musl", target_env = "sgx"))))'.dependencies]
44-
mimalloc = "0.1"
45-
4643
[target.'cfg(windows)'.dependencies]
4744
libc = { workspace = true }
4845

src/main.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
#[cfg(all(
2-
any(target_os = "linux", target_os = "macos", target_os = "windows"),
3-
not(any(target_env = "musl", target_env = "sgx"))
4-
))]
5-
mod _alloc {
6-
use mimalloc::MiMalloc;
1+
use rustpython_vm::RustPythonAllocator;
72

8-
#[global_allocator]
9-
static GLOBAL: MiMalloc = MiMalloc;
10-
}
3+
#[global_allocator]
4+
static ALLOCATOR: RustPythonAllocator = RustPythonAllocator::new();
115

126
pub fn main() -> std::process::ExitCode {
137
rustpython::run(|_vm| {})

vm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ widestring = { workspace = true }
108108
[target.'cfg(all(any(target_os = "linux", target_os = "macos", target_os = "windows"), not(any(target_env = "musl", target_env = "sgx"))))'.dependencies]
109109
libffi = { workspace = true, features = ["system"] }
110110
libloading = "0.8"
111+
mimalloc = "0.1"
111112

112113
[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies]
113114
num_cpus = "1.13.1"

vm/src/alloc.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//! Configurable allocator for RustPython.
2+
//! Currently it supports `mimalloc` and `system` allocators,
3+
//! whereas cpython uses `pymalloc`` for most operations.
4+
5+
#[cfg(all(
6+
any(target_os = "linux", target_os = "macos", target_os = "windows"),
7+
not(any(target_env = "musl", target_env = "sgx"))
8+
))]
9+
mod inner {
10+
use std::alloc::{GlobalAlloc, Layout, System};
11+
12+
pub enum RustPythonAllocator {
13+
System(System),
14+
Mimalloc(mimalloc::MiMalloc),
15+
}
16+
17+
impl RustPythonAllocator {
18+
pub fn new(allocator: &str) -> Self {
19+
match allocator {
20+
"system" | "malloc" => RustPythonAllocator::System(System),
21+
"pymalloc" | "mimalloc" | "default" => {
22+
RustPythonAllocator::Mimalloc(mimalloc::MiMalloc)
23+
}
24+
_ => RustPythonAllocator::System(System),
25+
}
26+
}
27+
}
28+
29+
unsafe impl GlobalAlloc for RustPythonAllocator {
30+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
31+
unsafe {
32+
match self {
33+
RustPythonAllocator::System(system) => system.alloc(layout),
34+
RustPythonAllocator::Mimalloc(mimalloc) => mimalloc.alloc(layout),
35+
}
36+
}
37+
}
38+
39+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
40+
unsafe {
41+
match self {
42+
RustPythonAllocator::System(system) => system.dealloc(ptr, layout),
43+
RustPythonAllocator::Mimalloc(mimalloc) => mimalloc.dealloc(ptr, layout),
44+
}
45+
}
46+
}
47+
}
48+
}
49+
50+
#[cfg(not(all(
51+
any(target_os = "linux", target_os = "macos", target_os = "windows"),
52+
not(any(target_env = "musl", target_env = "sgx"))
53+
)))]
54+
mod inner {
55+
use std::alloc::{GlobalAlloc, Layout, System};
56+
57+
pub enum RustPythonAllocator {
58+
System(System),
59+
}
60+
61+
impl RustPythonAllocator {
62+
pub fn new(_allocator: &str) -> Self {
63+
RustPythonAllocator::System(System)
64+
}
65+
}
66+
67+
impl GlobalAlloc for RustPythonAllocator {
68+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
69+
unsafe { self.0.alloc(layout) }
70+
}
71+
72+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
73+
unsafe { self.0.dealloc(ptr, layout) }
74+
}
75+
}
76+
}
77+
78+
use std::alloc::{GlobalAlloc, Layout};
79+
use std::cell::UnsafeCell;
80+
81+
pub use inner::RustPythonAllocator as InternalAllocator;
82+
83+
pub struct RustPythonAllocator {
84+
inner: UnsafeCell<InternalAllocator>,
85+
}
86+
87+
unsafe impl Send for RustPythonAllocator {}
88+
unsafe impl Sync for RustPythonAllocator {}
89+
90+
impl RustPythonAllocator {
91+
/// Create a new allocator based on the PYTHONMALLOC environment variable
92+
/// or the default allocator if not set.
93+
/// If this is not intended, use [`InternalAllocator::new`] directly.
94+
pub const fn new() -> Self {
95+
Self {
96+
inner: UnsafeCell::new(None),
97+
}
98+
}
99+
}
100+
101+
impl RustPythonAllocator {
102+
unsafe fn get_or_init(&self) -> &InternalAllocator {
103+
unsafe {
104+
let inner = self.inner.get();
105+
if *inner.is_none() {
106+
let env = std::env::var("PYTHONMALLOC").unwrap_or_default();
107+
let allocator = InternalAllocator::new(&env);
108+
*inner = allocator;
109+
}
110+
inner as *const InternalAllocator as _
111+
}
112+
}
113+
}
114+
115+
unsafe impl GlobalAlloc for RustPythonAllocator {
116+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
117+
unsafe {
118+
let inner = self.get_or_init();
119+
inner.alloc(layout)
120+
}
121+
}
122+
123+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
124+
unsafe {
125+
let inner = self.get_or_init();
126+
inner.dealloc(ptr, layout)
127+
}
128+
}
129+
}

vm/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub use rustpython_derive::*;
4040
#[macro_use]
4141
pub(crate) mod macros;
4242

43+
mod alloc;
4344
mod anystr;
4445
pub mod buffer;
4546
pub mod builtins;
@@ -85,6 +86,7 @@ pub mod warn;
8586
#[cfg(windows)]
8687
pub mod windows;
8788

89+
pub use self::alloc::RustPythonAllocator;
8890
pub use self::compiler::source;
8991
pub use self::convert::{TryFromBorrowedObject, TryFromObject};
9092
pub use self::object::{

0 commit comments

Comments
 (0)