1#![feature(
17 const_type_id,
18 const_refs_to_cell,
19 const_type_name,
20 panic_always_abort,
21 ptr_metadata,
22 core_intrinsics,
23 specialization,
24 thread_local,
25 ptr_sub_ptr,
26 portable_simd,
27 arbitrary_self_types
28)]
29#![allow(dead_code, unused_imports, incomplete_features)]
30
31use std::{cell::UnsafeCell, sync::atomic::AtomicPtr};
32
33pub mod heap;
34pub mod sync;
35pub mod system;
36pub mod utils;
37
38pub struct FormattedSize {
39 pub size: f64,
40}
41
42impl std::fmt::Display for FormattedSize {
43 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
44 let ksize = (self.size as f64) / 1024f64;
45
46 if ksize < 1f64 {
47 return write!(f, "{}B", self.size);
48 }
49
50 let msize = ksize / 1024f64;
51
52 if msize < 1f64 {
53 return write!(f, "{:.1}K", ksize);
54 }
55
56 let gsize = msize / 1024f64;
57
58 if gsize < 8f64 {
59 write!(f, "{:.1}M", msize)
60 } else {
61 write!(f, "{:.1}G", gsize)
62 }
63 }
64}
65
66impl std::fmt::Debug for FormattedSize {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{}", self)
69 }
70}
71
72pub fn formatted_size(size: usize) -> FormattedSize {
73 FormattedSize { size: size as f64 }
74}
75
76pub fn formatted_sizef(size: f64) -> FormattedSize {
77 FormattedSize { size: size as f64 }
78}
79
80static mut SINK: usize = 0;
81
82pub fn force_on_stack<T>(val: *const T) {
83 unsafe {
84 core::ptr::write_volatile(&mut SINK, val as usize);
85 core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
86 }
87}
88
89#[macro_export]
90macro_rules! offsetof {
91 ($obj: ty, $($field: ident).+) => {{
92 #[allow(unused_unsafe)]
93 unsafe {
94 let addr = 0x4000 as *const $obj;
95 &(*addr).$($field).* as *const _ as usize - 0x4000
96 }
97 }
98 };
99}
100
101pub use heap::thread;
102use system::object::Allocation;
103
104pub const fn needs_write_barrier<T: Allocation>() -> bool {
108 !T::NO_HEAP_PTRS || (T::VARSIZE && !T::VARSIZE_NO_HEAP_PTRS)
109}
110
111pub mod prelude {
112 pub use super::heap;
113 pub use super::system;
114 pub use heap::thread::*;
115 pub use heap::region::*;
116 pub use system::{object::*, traits::*};
117}
118
119cfg_if::cfg_if! {
120 if #[cfg(not(any(feature="gc-satb", feature="gc-incremental-update", feature="gc-passive")))] {
121 compile_error!("No GC mode selected, enable one of through features: gc-satb, gc-incremental-update, gc-passive");
122 } else if #[cfg(all(feature="gc-satb", not(feature="gc-incremental-update"), not(feature = "gc-passive")))] {
123 } else if #[cfg(all(feature="gc-incremental-update", not(feature="gc-satb"), not(feature = "gc-passive")))] {
124 } else if #[cfg(all(feature="gc-passive", not(feature="gc-satb"), not(feature = "gc-incremental-update")))] {
125 } else {
126 compile_error!("Multiple GC modes selected, enable only one of through features: gc-satb, gc-incremental-update, gc-passive");
127 }
128}
129
130pub fn new_i32(thread: &mut prelude::Thread, x: i32) -> prelude::Handle<i32> {
131 let handle = thread.allocate(x);
132 handle
133}