]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_arena/src/tests.rs
Rollup merge of #81837 - gilescope:to_ascii_speedups, r=dtolnay
[rust.git] / compiler / rustc_arena / src / tests.rs
1 extern crate test;
2 use super::TypedArena;
3 use std::cell::Cell;
4 use test::Bencher;
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 { inner: arena.alloc_inner(|| Inner { value: 10 }) });
57
58     assert_eq!(result.inner.value, 10);
59 }
60
61 #[test]
62 pub fn test_copy() {
63     let arena = TypedArena::default();
64     for _ in 0..100000 {
65         arena.alloc(Point { x: 1, y: 2, z: 3 });
66     }
67 }
68
69 #[bench]
70 pub fn bench_copy(b: &mut Bencher) {
71     let arena = TypedArena::default();
72     b.iter(|| arena.alloc(Point { x: 1, y: 2, z: 3 }))
73 }
74
75 #[bench]
76 pub fn bench_copy_nonarena(b: &mut Bencher) {
77     b.iter(|| {
78         let _: Box<_> = Box::new(Point { x: 1, y: 2, z: 3 });
79     })
80 }
81
82 #[allow(dead_code)]
83 struct Noncopy {
84     string: String,
85     array: Vec<i32>,
86 }
87
88 #[test]
89 pub fn test_noncopy() {
90     let arena = TypedArena::default();
91     for _ in 0..100000 {
92         arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
93     }
94 }
95
96 #[test]
97 pub fn test_typed_arena_zero_sized() {
98     let arena = TypedArena::default();
99     for _ in 0..100000 {
100         arena.alloc(());
101     }
102 }
103
104 #[test]
105 pub fn test_typed_arena_clear() {
106     let mut arena = TypedArena::default();
107     for _ in 0..10 {
108         arena.clear();
109         for _ in 0..10000 {
110             arena.alloc(Point { x: 1, y: 2, z: 3 });
111         }
112     }
113 }
114
115 #[bench]
116 pub fn bench_typed_arena_clear(b: &mut Bencher) {
117     let mut arena = TypedArena::default();
118     b.iter(|| {
119         arena.alloc(Point { x: 1, y: 2, z: 3 });
120         arena.clear();
121     })
122 }
123
124 #[bench]
125 pub fn bench_typed_arena_clear_100(b: &mut Bencher) {
126     let mut arena = TypedArena::default();
127     b.iter(|| {
128         for _ in 0..100 {
129             arena.alloc(Point { x: 1, y: 2, z: 3 });
130         }
131         arena.clear();
132     })
133 }
134
135 // Drop tests
136
137 struct DropCounter<'a> {
138     count: &'a Cell<u32>,
139 }
140
141 impl Drop for DropCounter<'_> {
142     fn drop(&mut self) {
143         self.count.set(self.count.get() + 1);
144     }
145 }
146
147 #[test]
148 fn test_typed_arena_drop_count() {
149     let counter = Cell::new(0);
150     {
151         let arena: TypedArena<DropCounter<'_>> = TypedArena::default();
152         for _ in 0..100 {
153             // Allocate something with drop glue to make sure it doesn't leak.
154             arena.alloc(DropCounter { count: &counter });
155         }
156     };
157     assert_eq!(counter.get(), 100);
158 }
159
160 #[test]
161 fn test_typed_arena_drop_on_clear() {
162     let counter = Cell::new(0);
163     let mut arena: TypedArena<DropCounter<'_>> = TypedArena::default();
164     for i in 0..10 {
165         for _ in 0..100 {
166             // Allocate something with drop glue to make sure it doesn't leak.
167             arena.alloc(DropCounter { count: &counter });
168         }
169         arena.clear();
170         assert_eq!(counter.get(), i * 100 + 100);
171     }
172 }
173
174 thread_local! {
175     static DROP_COUNTER: Cell<u32> = Cell::new(0)
176 }
177
178 struct SmallDroppable;
179
180 impl Drop for SmallDroppable {
181     fn drop(&mut self) {
182         DROP_COUNTER.with(|c| c.set(c.get() + 1));
183     }
184 }
185
186 #[test]
187 fn test_typed_arena_drop_small_count() {
188     DROP_COUNTER.with(|c| c.set(0));
189     {
190         let arena: TypedArena<SmallDroppable> = TypedArena::default();
191         for _ in 0..100 {
192             // Allocate something with drop glue to make sure it doesn't leak.
193             arena.alloc(SmallDroppable);
194         }
195         // dropping
196     };
197     assert_eq!(DROP_COUNTER.with(|c| c.get()), 100);
198 }
199
200 #[bench]
201 pub fn bench_noncopy(b: &mut Bencher) {
202     let arena = TypedArena::default();
203     b.iter(|| {
204         arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] })
205     })
206 }
207
208 #[bench]
209 pub fn bench_noncopy_nonarena(b: &mut Bencher) {
210     b.iter(|| {
211         let _: Box<_> =
212             Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
213     })
214 }