Skip to content

Commit f7fe286

Browse files
committed
tests
1 parent ae227b5 commit f7fe286

File tree

3 files changed

+118
-19
lines changed

3 files changed

+118
-19
lines changed

src/alloc/alloc_bytes.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,14 @@ impl Drop for MiriAllocBytes {
5555
MiriByteMdata::Global => alloc::dealloc(self.ptr, alloc_layout),
5656
MiriByteMdata::Isolated => {
5757
#[cfg(target_os = "linux")]
58-
{MachineAlloc::dealloc(self.ptr, alloc_layout)}
58+
{
59+
MachineAlloc::dealloc(self.ptr, alloc_layout)
60+
}
5961
#[cfg(not(target_os = "linux"))]
60-
{unreachable!()}
61-
},
62+
{
63+
unreachable!()
64+
}
65+
}
6266
}
6367
}
6468
}
@@ -121,10 +125,14 @@ impl AllocBytes for MiriAllocBytes {
121125
MiriByteMdata::Global => alloc::alloc(layout),
122126
MiriByteMdata::Isolated => {
123127
#[cfg(target_os = "linux")]
124-
{MachineAlloc::alloc(layout)}
128+
{
129+
MachineAlloc::alloc(layout)
130+
}
125131
#[cfg(not(target_os = "linux"))]
126-
{unreachable!()}
127-
},
132+
{
133+
unreachable!()
134+
}
135+
}
128136
}
129137
};
130138
let alloc_bytes = MiriAllocBytes::alloc_with(size.to_u64(), align, dsc, alloc_fn)
@@ -146,10 +154,14 @@ impl AllocBytes for MiriAllocBytes {
146154
MiriByteMdata::Global => alloc::alloc_zeroed(layout),
147155
MiriByteMdata::Isolated => {
148156
#[cfg(target_os = "linux")]
149-
{MachineAlloc::alloc_zeroed(layout)}
157+
{
158+
MachineAlloc::alloc_zeroed(layout)
159+
}
150160
#[cfg(not(target_os = "linux"))]
151-
{unreachable!()}
152-
},
161+
{
162+
unreachable!()
163+
}
164+
}
153165
}
154166
};
155167
MiriAllocBytes::alloc_with(size, align, dsc, alloc_fn).ok()

src/alloc/discrete_alloc.rs

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,7 @@ impl MachineAlloc {
3535
/// allow this function to be `const`; it is updated to its real value on
3636
/// the first call to `alloc()` or `alloc_zeroed()`.
3737
const fn empty() -> Self {
38-
Self {
39-
pages: Vec::new(),
40-
huge_allocs: Vec::new(),
41-
allocated: Vec::new(),
42-
page_size: 0,
43-
}
38+
Self { pages: Vec::new(), huge_allocs: Vec::new(), allocated: Vec::new(), page_size: 0 }
4439
}
4540

4641
/// Expands the available memory pool by adding one page.
@@ -68,9 +63,7 @@ impl MachineAlloc {
6863
#[inline]
6964
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
7065
let mut alloc = ALLOCATOR.lock().unwrap();
71-
unsafe {
72-
alloc.alloc_inner(layout, false)
73-
}
66+
unsafe { alloc.alloc_inner(layout, false) }
7467
}
7568

7669
/// Same as `alloc()`, but zeroes out data before allocating.
@@ -199,3 +192,93 @@ impl MachineAlloc {
199192
}
200193
}
201194
}
195+
196+
#[cfg(test)]
197+
mod tests {
198+
use super::*;
199+
200+
fn assert_zeroes(ptr: *mut u8, layout: Layout) {
201+
unsafe {
202+
for ofs in 0..layout.size() {
203+
assert_eq!(0, ptr.offset(ofs as isize).read());
204+
}
205+
}
206+
}
207+
208+
#[test]
209+
fn small_zeroes() {
210+
let layout = Layout::from_size_align(256, 32).unwrap();
211+
let ptr = unsafe { MachineAlloc::alloc_zeroed(layout) };
212+
assert_zeroes(ptr, layout);
213+
unsafe {
214+
MachineAlloc::dealloc(ptr, layout);
215+
}
216+
}
217+
218+
#[test]
219+
fn big_zeroes() {
220+
let layout = Layout::from_size_align(16 * 1024, 128).unwrap();
221+
let ptr = unsafe { MachineAlloc::alloc_zeroed(layout) };
222+
assert_zeroes(ptr, layout);
223+
unsafe {
224+
MachineAlloc::dealloc(ptr, layout);
225+
}
226+
}
227+
228+
#[test]
229+
fn repeated_allocs() {
230+
for sz in (1..=(16 * 1024)).step_by(128) {
231+
let layout = Layout::from_size_align(sz, 1).unwrap();
232+
let ptr = unsafe { MachineAlloc::alloc_zeroed(layout) };
233+
assert_zeroes(ptr, layout);
234+
unsafe {
235+
ptr.write_bytes(255, sz);
236+
MachineAlloc::dealloc(ptr, layout);
237+
}
238+
}
239+
}
240+
241+
#[test]
242+
fn no_overlaps() {
243+
// Some random sizes and aligns
244+
let mut sizes = vec![32; 10];
245+
sizes.append(&mut vec![15; 4]);
246+
sizes.append(&mut vec![256; 12]);
247+
// Give it some multi-page ones too
248+
sizes.append(&mut vec![32*1024; 4]);
249+
250+
let mut aligns = vec![16; 12];
251+
aligns.append(&mut vec![256; 2]);
252+
aligns.append(&mut vec![64; 12]);
253+
aligns.append(&mut vec![4096; 4]);
254+
255+
assert_eq!(sizes.len(), aligns.len());
256+
let layouts: Vec<_> = std::iter::zip(sizes, aligns)
257+
.map(|(sz, al)| Layout::from_size_align(sz, al).unwrap())
258+
.collect();
259+
let ptrs: Vec<_> = layouts.iter().map(|layout| unsafe { MachineAlloc::alloc_zeroed(*layout) }).collect();
260+
261+
for (&ptr, &layout) in std::iter::zip(&ptrs, &layouts) {
262+
// Make sure we don't allocate overlapping ranges
263+
unsafe {
264+
assert_zeroes(ptr, layout);
265+
ptr.write_bytes(255, layout.size());
266+
MachineAlloc::dealloc(ptr, layout);
267+
}
268+
}
269+
}
270+
271+
#[test]
272+
fn check_leaks() {
273+
// In case this test gets run on its own, make sure to generate some
274+
// noise in the allocator.
275+
no_overlaps();
276+
277+
let alloc = ALLOCATOR.lock().unwrap();
278+
for pinfo in &alloc.allocated {
279+
for eight_bytes in 0..pinfo.len() {
280+
assert_eq!(eight_bytes, 0);
281+
}
282+
}
283+
}
284+
}

src/concurrency/thread.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
900900
let mut alloc = alloc.inner().adjust_from_tcx(
901901
&this.tcx,
902902
|bytes, align| {
903-
interp_ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align, dsc))
903+
interp_ok(MiriAllocBytes::from_bytes(
904+
std::borrow::Cow::Borrowed(bytes),
905+
align,
906+
dsc,
907+
))
904908
},
905909
|ptr| this.global_root_pointer(ptr),
906910
)?;

0 commit comments

Comments
 (0)