1use rb_sys::{rb_gc_adjust_memory_usage, ssize_t};
8use std::alloc::{GlobalAlloc, Layout, System};
9
10pub struct RbAllocator;
11
12unsafe impl GlobalAlloc for RbAllocator {
13 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
14 let ret = System.alloc(layout);
15 if !ret.is_null() {
16 rb_gc_adjust_memory_usage(layout.size() as ssize_t)
17 }
18 ret
19 }
20
21 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
22 let ret = System.alloc_zeroed(layout);
23 if !ret.is_null() {
24 rb_gc_adjust_memory_usage(layout.size() as ssize_t)
25 }
26 ret
27 }
28
29 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
30 System.dealloc(ptr, layout);
31 rb_gc_adjust_memory_usage(0 - (layout.size() as ssize_t));
32 }
33
34 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
35 let ret = System.realloc(ptr, layout, new_size);
36 if !ret.is_null() {
37 rb_gc_adjust_memory_usage((new_size as isize - layout.size() as isize) as ssize_t);
38 }
39 ret
40 }
41}
42
43#[macro_export]
44macro_rules! ruby_global_allocator {
45 () => {
46 use $crate::RbAllocator;
47 #[global_allocator]
48 static RUBY_GLOBAL_ALLOCATOR: RbAllocator = RbAllocator;
49 };
50}