1#[macro_export]
8macro_rules! impl_advanced_trackable {
9 ($type:ty, $offset:expr) => {
10 impl<T> $crate::Trackable for $type {
11 fn get_heap_ptr(&self) -> Option<usize> {
12 let instance_ptr = self as *const _ as usize;
14 Some($offset + (instance_ptr % 0x0FFF_FFFF))
15 }
16
17 fn get_type_name(&self) -> &'static str {
18 std::any::type_name::<$type>()
19 }
20
21 fn get_size_estimate(&self) -> usize {
22 std::mem::size_of::<$type>()
23 }
24
25 fn get_advanced_type_info(&self) -> Option<$crate::advanced_types::AdvancedTypeInfo> {
26 let type_name = self.get_type_name();
27 let allocation = $crate::core::types::AllocationInfo {
28 ptr: self.get_heap_ptr().unwrap_or(0),
29 size: self.get_size_estimate(),
30 var_name: None,
31 type_name: Some(type_name.to_string()),
32 scope_name: None,
33 timestamp_alloc: std::time::SystemTime::now()
34 .duration_since(std::time::UNIX_EPOCH)
35 .unwrap_or_default()
36 .as_nanos() as u64,
37 timestamp_dealloc: None,
38 thread_id: format!("{:?}", std::thread::current().id()),
39 borrow_count: 0,
40 stack_trace: None,
41 is_leaked: false,
42 lifetime_ms: None,
43 borrow_info: None,
44 clone_info: None,
45 ownership_history_available: false,
46 smart_pointer_info: None,
47 memory_layout: None,
48 generic_info: None,
49 dynamic_type_info: None,
50 runtime_state: None,
51 stack_allocation: None,
52 temporary_object: None,
53 fragmentation_analysis: None,
54 generic_instantiation: None,
55 type_relationships: None,
56 type_usage: None,
57 function_call_tracking: None,
58 lifecycle_tracking: None,
59 access_tracking: None,
60 drop_chain_analysis: None,
61 };
62
63 Some(
64 $crate::advanced_types::GenericAdvancedTypeAnalyzer::analyze_by_type_name(
65 type_name,
66 &allocation,
67 ),
68 )
69 }
70 }
71 };
72
73 ($type:ty, $offset:expr, no_generics) => {
75 impl $crate::Trackable for $type {
76 fn get_heap_ptr(&self) -> Option<usize> {
77 let instance_ptr = self as *const _ as usize;
78 Some($offset + (instance_ptr % 0x0FFF_FFFF))
79 }
80
81 fn get_type_name(&self) -> &'static str {
82 std::any::type_name::<$type>()
83 }
84
85 fn get_size_estimate(&self) -> usize {
86 std::mem::size_of::<$type>()
87 }
88
89 fn get_advanced_type_info(&self) -> Option<$crate::advanced_types::AdvancedTypeInfo> {
90 let type_name = self.get_type_name();
91 let allocation = $crate::core::types::AllocationInfo {
92 ptr: self.get_heap_ptr().unwrap_or(0),
93 size: self.get_size_estimate(),
94 var_name: None,
95 type_name: Some(type_name.to_string()),
96 scope_name: None,
97 timestamp_alloc: std::time::SystemTime::now()
98 .duration_since(std::time::UNIX_EPOCH)
99 .unwrap_or_default()
100 .as_nanos() as u64,
101 timestamp_dealloc: None,
102 thread_id: format!("{:?}", std::thread::current().id()),
103 borrow_count: 0,
104 stack_trace: None,
105 is_leaked: false,
106 lifetime_ms: None,
107 borrow_info: None,
108 clone_info: None,
109 ownership_history_available: false,
110 smart_pointer_info: None,
111 memory_layout: None,
112 generic_info: None,
113 dynamic_type_info: None,
114 runtime_state: None,
115 stack_allocation: None,
116 temporary_object: None,
117 fragmentation_analysis: None,
118 generic_instantiation: None,
119 type_relationships: None,
120 type_usage: None,
121 function_call_tracking: None,
122 lifecycle_tracking: None,
123 access_tracking: None,
124 drop_chain_analysis: None,
125 };
126
127 Some(
128 $crate::advanced_types::GenericAdvancedTypeAnalyzer::analyze_by_type_name(
129 type_name,
130 &allocation,
131 ),
132 )
133 }
134 }
135 };
136}
137
138#[cfg(test)]
139mod tests {
140 use crate::Trackable;
141 use std::cell::RefCell;
142 use std::sync::Mutex;
143
144 struct TestGenericStruct<T> {
146 #[allow(dead_code)]
147 data: T,
148 }
149
150 struct TestSimpleStruct {
152 #[allow(dead_code)]
153 value: i32,
154 }
155
156 impl_advanced_trackable!(TestGenericStruct<T>, 0x1000_0000);
158 impl_advanced_trackable!(TestSimpleStruct, 0x2000_0000, no_generics);
159
160 #[test]
161 fn test_generic_macro_implementation() {
162 let test_struct = TestGenericStruct { data: 42i32 };
163
164 let heap_ptr = test_struct.get_heap_ptr();
166 assert!(heap_ptr.is_some());
167 let ptr = heap_ptr.unwrap();
168 assert!(ptr >= 0x1000_0000);
169 assert!(ptr < 0x1000_0000 + 0x0FFF_FFFF);
170
171 let type_name = test_struct.get_type_name();
173 assert!(type_name.contains("TestGenericStruct"));
174 assert!(type_name.contains("i32"));
175
176 let size = test_struct.get_size_estimate();
178 assert_eq!(size, std::mem::size_of::<TestGenericStruct<i32>>());
179 }
180
181 #[test]
182 fn test_non_generic_macro_implementation() {
183 let test_struct = TestSimpleStruct { value: 123 };
184
185 let heap_ptr = test_struct.get_heap_ptr();
187 assert!(heap_ptr.is_some());
188 let ptr = heap_ptr.unwrap();
189 assert!(ptr >= 0x2000_0000);
190 assert!(ptr < 0x2000_0000 + 0x0FFF_FFFF);
191
192 let type_name = test_struct.get_type_name();
194 assert!(type_name.contains("TestSimpleStruct"));
195
196 let size = test_struct.get_size_estimate();
198 assert_eq!(size, std::mem::size_of::<TestSimpleStruct>());
199 }
200
201 #[test]
202 fn test_advanced_type_info_generation() {
203 let test_struct = TestGenericStruct {
204 data: "test".to_string(),
205 };
206
207 let advanced_info = test_struct.get_advanced_type_info();
209 assert!(advanced_info.is_some());
210
211 let info = advanced_info.unwrap();
212 assert!(!format!("{:?}", info.category).is_empty());
214 assert!(info.performance_info.overhead_factor >= 1.0);
216 }
217
218 #[test]
219 fn test_macro_with_different_offsets() {
220 let generic_struct = TestGenericStruct { data: 100u64 };
221 let simple_struct = TestSimpleStruct { value: 200 };
222
223 let generic_ptr = generic_struct.get_heap_ptr().unwrap();
224 let simple_ptr = simple_struct.get_heap_ptr().unwrap();
225
226 assert!((0x1000_0000..0x1000_0000 + 0x0FFF_FFFF).contains(&generic_ptr));
228 assert!((0x2000_0000..0x2000_0000 + 0x0FFF_FFFF).contains(&simple_ptr));
229
230 assert!((generic_ptr & 0xF000_0000) != (simple_ptr & 0xF000_0000));
232 }
233
234 #[test]
235 fn test_allocation_info_creation() {
236 let test_struct = TestGenericStruct {
237 data: RefCell::new(42),
238 };
239
240 let advanced_info = test_struct.get_advanced_type_info().unwrap();
241
242 assert!(advanced_info.state_info.is_borrowed.is_none());
246 assert!(advanced_info.state_info.is_locked.is_none());
247
248 let type_name = test_struct.get_type_name();
251 assert!(!type_name.is_empty());
252 }
253
254 #[test]
255 fn test_macro_with_interior_mutability_types() {
256 struct RefCellStruct {
258 #[allow(dead_code)]
259 data: RefCell<i32>,
260 }
261 impl_advanced_trackable!(RefCellStruct, 0x3000_0000, no_generics);
262
263 let refcell_struct = RefCellStruct {
264 data: RefCell::new(42),
265 };
266
267 let type_name = refcell_struct.get_type_name();
268 assert!(type_name.contains("RefCellStruct"));
269
270 let advanced_info = refcell_struct.get_advanced_type_info();
271 assert!(advanced_info.is_some());
272 }
273
274 #[test]
275 fn test_macro_with_sync_types() {
276 struct MutexStruct {
278 #[allow(dead_code)]
279 data: Mutex<String>,
280 }
281 impl_advanced_trackable!(MutexStruct, 0x4000_0000, no_generics);
282
283 let mutex_struct = MutexStruct {
284 data: Mutex::new("test".to_string()),
285 };
286
287 let type_name = mutex_struct.get_type_name();
288 assert!(type_name.contains("MutexStruct"));
289
290 let heap_ptr = mutex_struct.get_heap_ptr().unwrap();
291 assert!(heap_ptr >= 0x4000_0000);
292
293 let advanced_info = mutex_struct.get_advanced_type_info();
294 assert!(advanced_info.is_some());
295 }
296
297 #[test]
298 fn test_unique_pointer_generation() {
299 let struct1 = TestSimpleStruct { value: 1 };
301 let struct2 = TestSimpleStruct { value: 2 };
302 let struct3 = TestSimpleStruct { value: 3 };
303
304 let ptr1 = struct1.get_heap_ptr().unwrap();
305 let ptr2 = struct2.get_heap_ptr().unwrap();
306 let ptr3 = struct3.get_heap_ptr().unwrap();
307
308 assert!(ptr1 >= 0x2000_0000);
310 assert!(ptr2 >= 0x2000_0000);
311 assert!(ptr3 >= 0x2000_0000);
312
313 assert!(ptr1 != ptr2 || ptr2 != ptr3 || ptr1 != ptr3);
315 }
316
317 #[test]
318 fn test_generic_type_with_different_parameters() {
319 let int_struct = TestGenericStruct { data: 42i32 };
320 let string_struct = TestGenericStruct {
321 data: "hello".to_string(),
322 };
323 let vec_struct = TestGenericStruct {
324 data: vec![1, 2, 3],
325 };
326
327 let int_type = int_struct.get_type_name();
329 let string_type = string_struct.get_type_name();
330 let vec_type = vec_struct.get_type_name();
331
332 assert!(int_type.contains("i32"));
333 assert!(string_type.contains("String"));
334 assert!(vec_type.contains("Vec"));
335
336 let int_ptr = int_struct.get_heap_ptr().unwrap();
338 let string_ptr = string_struct.get_heap_ptr().unwrap();
339 let vec_ptr = vec_struct.get_heap_ptr().unwrap();
340
341 assert!((0x1000_0000..0x1000_0000 + 0x0FFF_FFFF).contains(&int_ptr));
342 assert!((0x1000_0000..0x1000_0000 + 0x0FFF_FFFF).contains(&string_ptr));
343 assert!((0x1000_0000..0x1000_0000 + 0x0FFF_FFFF).contains(&vec_ptr));
344 }
345
346 #[test]
347 fn test_size_estimation_accuracy() {
348 let simple_struct = TestSimpleStruct { value: 42 };
349 let generic_struct = TestGenericStruct { data: 123u64 };
350
351 let simple_size = simple_struct.get_size_estimate();
352 let generic_size = generic_struct.get_size_estimate();
353
354 assert_eq!(simple_size, std::mem::size_of::<TestSimpleStruct>());
356 assert_eq!(generic_size, std::mem::size_of::<TestGenericStruct<u64>>());
357
358 assert!(simple_size <= generic_size);
360 }
361
362 #[test]
363 fn test_macro_thread_safety() {
364 use std::sync::atomic::{AtomicUsize, Ordering};
365 use std::sync::Arc;
366 use std::thread;
367
368 let counter = Arc::new(AtomicUsize::new(0));
369 let mut handles = vec![];
370
371 for _ in 0..4 {
373 let counter_clone = counter.clone();
374 let handle = thread::spawn(move || {
375 let test_struct = TestSimpleStruct { value: 42 };
376 let _ptr = test_struct.get_heap_ptr();
377 let _type_name = test_struct.get_type_name();
378 let _size = test_struct.get_size_estimate();
379 counter_clone.fetch_add(1, Ordering::SeqCst);
380 });
381 handles.push(handle);
382 }
383
384 for handle in handles {
386 handle.join().unwrap();
387 }
388
389 assert_eq!(counter.load(Ordering::SeqCst), 4);
391 }
392
393 #[test]
394 fn test_allocation_info_fields() {
395 let test_struct = TestGenericStruct {
396 data: vec![1, 2, 3],
397 };
398 let advanced_info = test_struct.get_advanced_type_info().unwrap();
399
400 assert!(advanced_info.state_info.is_borrowed.is_none());
404 assert!(advanced_info.state_info.borrow_count.is_none());
405 assert!(advanced_info.state_info.is_locked.is_none());
406
407 assert!(advanced_info.performance_info.overhead_factor >= 1.0);
409 assert!(!format!("{:?}", advanced_info.category).is_empty());
413 assert!(!format!("{:?}", advanced_info.behavior).is_empty());
414 }
415}