]> git.lizzy.rs Git - rust.git/blob - src/libarena/tests.rs
Rollup merge of #67026 - Nadrieril:improve-usefulness-empty, r=varkor,Centril,estebank
[rust.git] / src / libarena / tests.rs
1 extern crate test;
2 use test::Bencher;
3 use super::TypedArena;
4 use std::cell::Cell;
5
6 #[allow(dead_code)]
7 #[derive(Debug, Eq, PartialEq)]
8 struct Point {
9     x: i32,
10     y: i32,
11     z: i32,
12 }
13
14 #[test]
15 pub fn test_unused() {
16     let arena: TypedArena<Point> = TypedArena::default();
17     assert!(arena.chunks.borrow().is_empty());
18 }
19
20 #[test]
21 fn test_arena_alloc_nested() {
22     struct Inner {
23         value: u8,
24     }
25     struct Outer<'a> {
26         inner: &'a Inner,
27     }
28     enum EI<'e> {
29         I(Inner),
30         O(Outer<'e>),
31     }
32
33     struct Wrap<'a>(TypedArena<EI<'a>>);
34
35     impl<'a> Wrap<'a> {
36         fn alloc_inner<F: Fn() -> Inner>(&self, f: F) -> &Inner {
37             let r: &EI<'_> = self.0.alloc(EI::I(f()));
38             if let &EI::I(ref i) = r {
39                 i
40             } else {
41                 panic!("mismatch");
42             }
43         }
44         fn alloc_outer<F: Fn() -> Outer<'a>>(&self, f: F) -> &Outer<'_> {
45             let r: &EI<'_> = self.0.alloc(EI::O(f()));
46             if let &EI::O(ref o) = r {
47                 o
48             } else {
49                 panic!("mismatch");
50             }
51         }
52     }
53
54     let arena = Wrap(TypedArena::default());
55
56     let result = arena.alloc_outer(|| Outer {
57         inner: arena.alloc_inner(|| Inner { value: 10 }),
58     });
59
60     assert_eq!(result.inner.value, 10);
61 }
62
63 #[test]
64 pub fn test_copy() {
65     let arena = TypedArena::default();
66     for _ in 0..100000 {
67         arena.alloc(Point { x: 1, y: 2, z: 3 });
68     }
69 }
70
71 #[bench]
72 pub fn bench_copy(b: &mut Bencher) {
73     let arena = TypedArena::default();
74     b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
75 }
76
77 #[bench]
78 pub fn bench_copy_nonarena(b: &mut Bencher) {
79     b.iter(|| {
80         let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 });
81     })
82 }
83
84 #[allow(dead_code)]
85 struct Noncopy {
86     string: String,
87     array: Vec<i32>,
88 }
89
90 #[test]
91 pub fn test_noncopy() {
92     let arena = TypedArena::default();
93     for _ in 0..100000 {
94         arena.alloc(Noncopy {
95             string: "hello world".to_string(),
96             array: vec![1, 2, 3, 4, 5],
97         });
98     }
99 }
100
101 #[test]
102 pub fn test_typed_arena_zero_sized() {
103     let arena = TypedArena::default();
104     for _ in 0..100000 {
105         arena.alloc(());
106     }
107 }
108
109 #[test]
110 pub fn test_typed_arena_clear() {
111     let mut arena = TypedArena::default();
112     for _ in 0..10 {
113         arena.clear();
114         for _ in 0..10000 {
115             arena.alloc(Point { x: 1, y: 2, z: 3 });
116         }
117     }
118 }
119
120 #[bench]
121 pub fn bench_typed_arena_clear(b: &mut Bencher) {
122     let mut arena = TypedArena::default();
123     b.iter(|| {
124         arena.alloc(Point { x: 1, y: 2, z: 3 });
125         arena.clear();
126     })
127 }
128
129 // Drop tests
130
131 struct DropCounter<'a> {
132     count: &'a Cell<u32>,
133 }
134
135 impl Drop for DropCounter<'_> {
136     fn drop(&mut self) {
137         self.count.set(self.count.get() + 1);
138     }
139 }
140
141 #[test]
142 fn test_typed_arena_drop_count() {
143     let counter = Cell::new(0);
144     {
145         let arena: TypedArena<DropCounter<'_>> = TypedArena::default();
146         for _ in 0..100 {
147             // Allocate something with drop glue to make sure it doesn't leak.
148             arena.alloc(DropCounter { count: &counter });
149         }
150     };
151     assert_eq!(counter.get(), 100);
152 }
153
154 #[test]
155 fn test_typed_arena_drop_on_clear() {
156     let counter = Cell::new(0);
157     let mut arena: TypedArena<DropCounter<'_>> = TypedArena::default();
158     for i in 0..10 {
159         for _ in 0..100 {
160             // Allocate something with drop glue to make sure it doesn't leak.
161             arena.alloc(DropCounter { count: &counter });
162         }
163         arena.clear();
164         assert_eq!(counter.get(), i * 100 + 100);
165     }
166 }
167
168 thread_local! {
169     static DROP_COUNTER: Cell<u32> = Cell::new(0)
170 }
171
172 struct SmallDroppable;
173
174 impl Drop for SmallDroppable {
175     fn drop(&mut self) {
176         DROP_COUNTER.with(|c| c.set(c.get() + 1));
177     }
178 }
179
180 #[test]
181 fn test_typed_arena_drop_small_count() {
182     DROP_COUNTER.with(|c| c.set(0));
183     {
184         let arena: TypedArena<SmallDroppable> = TypedArena::default();
185         for _ in 0..100 {
186             // Allocate something with drop glue to make sure it doesn't leak.
187             arena.alloc(SmallDroppable);
188         }
189         // dropping
190     };
191     assert_eq!(DROP_COUNTER.with(|c| c.get()), 100);
192 }
193
194 #[bench]
195 pub fn bench_noncopy(b: &mut Bencher) {
196     let arena = TypedArena::default();
197     b.iter(|| {
198         arena.alloc(Noncopy {
199             string: "hello world".to_string(),
200             array: vec![1, 2, 3, 4, 5],
201         })
202     })
203 }
204
205 #[bench]
206 pub fn bench_noncopy_nonarena(b: &mut Bencher) {
207     b.iter(|| {
208         let _: Box<_> = Box::new(Noncopy {
209             string: "hello world".to_string(),
210             array: vec![1, 2, 3, 4, 5],
211         });
212     })
213 }