]> git.lizzy.rs Git - rust.git/blob - src/libarena/tests.rs
update
[rust.git] / src / libarena / 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 // Drop tests
125
126 struct DropCounter<'a> {
127     count: &'a Cell<u32>,
128 }
129
130 impl Drop for DropCounter<'_> {
131     fn drop(&mut self) {
132         self.count.set(self.count.get() + 1);
133     }
134 }
135
136 #[test]
137 fn test_typed_arena_drop_count() {
138     let counter = Cell::new(0);
139     {
140         let arena: TypedArena<DropCounter<'_>> = TypedArena::default();
141         for _ in 0..100 {
142             // Allocate something with drop glue to make sure it doesn't leak.
143             arena.alloc(DropCounter { count: &counter });
144         }
145     };
146     assert_eq!(counter.get(), 100);
147 }
148
149 #[test]
150 fn test_typed_arena_drop_on_clear() {
151     let counter = Cell::new(0);
152     let mut arena: TypedArena<DropCounter<'_>> = TypedArena::default();
153     for i in 0..10 {
154         for _ in 0..100 {
155             // Allocate something with drop glue to make sure it doesn't leak.
156             arena.alloc(DropCounter { count: &counter });
157         }
158         arena.clear();
159         assert_eq!(counter.get(), i * 100 + 100);
160     }
161 }
162
163 thread_local! {
164     static DROP_COUNTER: Cell<u32> = Cell::new(0)
165 }
166
167 struct SmallDroppable;
168
169 impl Drop for SmallDroppable {
170     fn drop(&mut self) {
171         DROP_COUNTER.with(|c| c.set(c.get() + 1));
172     }
173 }
174
175 #[test]
176 fn test_typed_arena_drop_small_count() {
177     DROP_COUNTER.with(|c| c.set(0));
178     {
179         let arena: TypedArena<SmallDroppable> = TypedArena::default();
180         for _ in 0..100 {
181             // Allocate something with drop glue to make sure it doesn't leak.
182             arena.alloc(SmallDroppable);
183         }
184         // dropping
185     };
186     assert_eq!(DROP_COUNTER.with(|c| c.get()), 100);
187 }
188
189 #[bench]
190 pub fn bench_noncopy(b: &mut Bencher) {
191     let arena = TypedArena::default();
192     b.iter(|| {
193         arena.alloc(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] })
194     })
195 }
196
197 #[bench]
198 pub fn bench_noncopy_nonarena(b: &mut Bencher) {
199     b.iter(|| {
200         let _: Box<_> =
201             Box::new(Noncopy { string: "hello world".to_string(), array: vec![1, 2, 3, 4, 5] });
202     })
203 }